/*
 *      configdialog.cpp
 *
 *      Copyright 2008 David Vachulka <david@konstrukce-cad.com>
 *      Copyright (C) 2004-2005 Sander Jansen (some code)
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#include "configdialog.h"
#include "keybindingsdialog.h"
#include "config.h"
#include "i18n.h"
#include "icons.h"
#include "utils.h"
#include "dxirc.h"

#define MAXBUFFER 2000
#define MAXVALUE  2000
#define HEADER "# dxirc smiley settings\n# path is relative to file\n# Example: /home/xxx/smile.png=:)\n"
#define preferences dxirc::instance()->getPreferences()

static FXIcon *createIconFromName(FXApp *app, const FXString& path)
{
    FXIconSource iconsource(app);
    FXIcon *icon = NULL;
    if(!FXStat::exists(path))
        return NULL;
    icon = iconsource.loadScaledIconFile(path,16);
    if(icon)
    {
        icon->blend(app->getBaseColor());
        icon->create();
        return icon;
    }
    return NULL;
}

static void updateLabelIcon(FXApp* app, FXLabel* label, const FXString& path)
{
    FXIconSource iconsource(app);
    FXIcon *icon = NULL;
    if(label->getIcon())
    {
        icon = label->getIcon();
        label->setIcon(NULL);
        delete icon;
        icon = NULL;
    }
    icon = iconsource.loadScaledIconFile(path,16);
    if(icon)
    {
        icon->blend(app->getBaseColor());
        icon->create();
        label->setIcon(icon);
    }
}

// Check if quotes are needed
static bool needquotes(const FXchar* text)
{
    register const FXchar *ptr=text;
    register FXuchar c;
    while((c=*ptr++)!='\0')
    {
        if(0x7f<=c || c<0x20 || c=='"' || c=='\'' || c=='\\' || (c==' ' && (ptr==(text+1) || *ptr=='\0'))) return true;
    }
    return false;
}

// Read string
static bool readString(FXFile& file, FXchar *buffer, FXint& bol, FXint& eol, FXint& end)
{
    register FXint n;
    do
    {
        if(eol >= end)
        {
            if(bol < end)
            {
                memmove(buffer, buffer + bol, end - bol);
            }
            end = end - bol;
            bol = 0;
            eol = end;
            n = file.readBlock(buffer + end, MAXBUFFER - end);
            if(n < 0) return false;
            end += n;
        }
    } while (eol < end && buffer[eol++] != '\n');
    return bol<eol;
}

// Write string
static bool writeString(FXFile& file, const FXchar* string)
{
    register FXint len = strlen(string);
    return file.writeBlock(string, len) == len;
}

FXDEFMAP(SmileyDialog) SmileyDialogMap[] = {
    FXMAPFUNC(SEL_COMMAND, SmileyDialog_ACCEPT, SmileyDialog::onAccept),
    FXMAPFUNC(SEL_COMMAND, SmileyDialog_CANCEL, SmileyDialog::onCancel),
    FXMAPFUNC(SEL_COMMAND, SmileyDialog_PATH, SmileyDialog::onPath)
};

FXIMPLEMENT(SmileyDialog, FXDialogBox, SmileyDialogMap, ARRAYNUMBER(SmileyDialogMap))

SmileyDialog::SmileyDialog(FXWindow* owner, FXString title, FXString smiley, FXString path)
        : FXDialogBox(owner, title, DECOR_RESIZE|DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0)
{
    FXHorizontalFrame *closeframe = new FXHorizontalFrame(this, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH);
    new dxEXButton(closeframe, _("&Cancel"), NULL, this, SmileyDialog_CANCEL, LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK, 0,0,0,0, 10,10,2,2);
    dxEXButton *ok = new dxEXButton(closeframe, _("&OK"), NULL, this, SmileyDialog_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK, 0,0,0,0, 10,10,2,2);
    ok->addHotKey(KEY_Return);

    FXMatrix *matrix = new FXMatrix(this,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    new FXLabel(matrix, _("Smiley:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    m_smileyText = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    if(!smiley.empty()) m_smileyText->setText(smiley);
    new FXLabel(matrix, _("Path:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXHorizontalFrame *pathframe = new FXHorizontalFrame(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,0,0, 0,0,0,0);
    m_pathText = new FXTextField(pathframe, 25, NULL, 0, TEXTFIELD_READONLY|FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_X);
    m_pathText->setBackColor(getApp()->getBaseColor());
    if(!path.empty()) m_pathText->setText(path);
    m_pathButton = new dxEXButton(pathframe, "...", NULL, this, SmileyDialog_PATH, FRAME_RAISED|FRAME_THICK);
    new FXLabel(matrix, _("Preview:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    m_previewLabel = new FXLabel(matrix, "", path.empty() ? NULL : createIconFromName(getApp(), path), JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
}

SmileyDialog::~SmileyDialog()
{

}

long SmileyDialog::onAccept(FXObject*, FXSelector, void*)
{
    getApp()->stopModal(this,TRUE);
    hide();
    return 1;
}

long SmileyDialog::onCancel(FXObject*, FXSelector, void*)
{
    getApp()->stopModal(this,FALSE);
    hide();
    return 1;
}

long SmileyDialog::onPath(FXObject*, FXSelector, void*)
{
    dxEXFileDialog dialog(this, _("Select file"));
    if(!m_pathText->getText().empty()) dialog.setFilename(m_pathText->getText());
    else dialog.setFilename((FXString)DXIRC_DATADIR+PATHSEPSTRING+"icons"+PATHSEPSTRING+"smileys"+PATHSEPSTRING);
    if(dialog.execute())
    {
        m_pathText->setText(dialog.getFilename());
        updateLabelIcon(getApp(), m_previewLabel, dialog.getFilename());
    }
    return 1;
}

FXbool SmileyDialog::iconExist()
{
    if(m_previewLabel->getIcon()) return TRUE;
    return FALSE;
}

FXDEFMAP(ConfigDialog) ConfigDialogMap[] = {
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_CLOSE, ConfigDialog::onClose),
    FXMAPFUNC(SEL_SELECTED, ConfigDialog_COMMAND, ConfigDialog::onCommandsSelected),
    FXMAPFUNC(SEL_DESELECTED, ConfigDialog_COMMAND, ConfigDialog::onCommandsDeselected),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_ADDCOMMAND, ConfigDialog::onAddCommand),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DELETECOMMAND, ConfigDialog::onDeleteCommand),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_ADDUSER, ConfigDialog::onAddUser),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_MODIFYUSER, ConfigDialog::onModifyUser),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DELETEUSER, ConfigDialog::onDeleteUser),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_ADDFRIEND, ConfigDialog::onAddFriend),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_MODIFYFRIEND, ConfigDialog::onModifyFriend),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DELETEFRIEND, ConfigDialog::onDeleteFriend),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_ICONS, ConfigDialog::onIconsChanged),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_ADDICONS, ConfigDialog::onAddIcons),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DELETEICONS, ConfigDialog::onDeleteIcons),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_TRAY, ConfigDialog::onTray),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_LOG, ConfigDialog::onLogChanged),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_LOGPATH, ConfigDialog::onPathSelect),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_AUTOLOAD, ConfigDialog::onAutoloadChanged),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_AUTOLOADPATH, ConfigDialog::onAutoloadPathSelect),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DCCPATH, ConfigDialog::onDccPathSelect),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_NICK, ConfigDialog::onNickCharChanged),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_RECONNECT, ConfigDialog::onReconnect),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_IRCCOLORS, ConfigDialog::onColor),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_IRCCOLORS, ConfigDialog::onColor),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_COLORS, ConfigDialog::onThemeColorChanged),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_COLORS, ConfigDialog::onThemeColorChanged),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_TABCOLORS, ConfigDialog::onTabColorChanged),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_TABCOLORS, ConfigDialog::onTabColorChanged),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_THEME, ConfigDialog::onTheme),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_FONT, ConfigDialog::onFont),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_IRCFONT, ConfigDialog::onIrcFont),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_TABPOS, ConfigDialog::onTabPosition),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_NOTIFYPOS, ConfigDialog::onNotifyPosition),
    FXMAPFUNC(SEL_SELECTED, ConfigDialog_USER, ConfigDialog::onUsersSelected),
    FXMAPFUNC(SEL_DESELECTED, ConfigDialog_USER, ConfigDialog::onUsersDeselected),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_USER, ConfigDialog::onUsersChanged),
    FXMAPFUNC(SEL_SELECTED, ConfigDialog_FRIEND, ConfigDialog::onFriendsSelected),
    FXMAPFUNC(SEL_DESELECTED, ConfigDialog_FRIEND, ConfigDialog::onFriendsDeselected),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_FRIEND, ConfigDialog::onFriendsChanged),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DCCPORTD, ConfigDialog::onDccPortD),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_DCCPORTD, ConfigDialog::onDccPortD),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DCCPORTH, ConfigDialog::onDccPortH),
    FXMAPFUNC(SEL_CHANGED, ConfigDialog_DCCPORTH, ConfigDialog::onDccPortH),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_SOUNDS, ConfigDialog::onSounds),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_SOUNDCONNECT, ConfigDialog::onSoundConnect),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_SOUNDDISCONNECT, ConfigDialog::onSoundDisconnect),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_SOUNDMESSAGE, ConfigDialog::onSoundMessage),
    FXMAPFUNCS(SEL_COMMAND, ConfigDialog_PLAYCONNECT, ConfigDialog_PLAYMESSAGE, ConfigDialog::onPlay),
    FXMAPFUNCS(SEL_COMMAND, ConfigDialog_SELECTCONNECT, ConfigDialog_SELECTMESSAGE, ConfigDialog::onSelectPath),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_NOTIFY, ConfigDialog::onNotify),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_SHOWNOTIFY, ConfigDialog::onShowNotify),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_USESMILEYS, ConfigDialog::onUseSmileys),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_ADDSMILEY, ConfigDialog::onAddSmiley),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_MODIFYSMILEY, ConfigDialog::onModifySmiley),
    FXMAPFUNC(SEL_DOUBLECLICKED, ConfigDialog_SMILEY, ConfigDialog::onModifySmiley),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_DELETESMILEY, ConfigDialog::onDeleteSmiley),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_IMPORTSMILEY, ConfigDialog::onImportSmiley),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_EXPORTSMILEY, ConfigDialog::onExportSmiley),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_LOADLOG, ConfigDialog::onLoadLog),
    FXMAPFUNC(SEL_MOUSEWHEEL, ConfigDialog_TABS, ConfigDialog::onMouseWheel),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_MODIFYBINDINGS, ConfigDialog::onModifyBindings),
    FXMAPFUNC(SEL_COMMAND, ConfigDialog_REFRESHBINDINGS, ConfigDialog::onRefreshBindings)
};

FXIMPLEMENT(ConfigDialog, FXDialogBox, ConfigDialogMap, ARRAYNUMBER(ConfigDialogMap))

ConfigDialog::ConfigDialog(FXMainWindow *owner)
    : FXDialogBox(owner, _("Preferences"), DECOR_RESIZE|DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0), m_owner(owner)
{
    m_preferences = preferences;
    //create m_ircFont
    if(!m_preferences.m_ircFont.empty())
    {
        m_ircFont = new FXFont(getApp(), m_preferences.m_ircFont);
        m_ircFont->create();
    }
    else
    {
        getApp()->getNormalFont()->create();
        FXFontDesc fontdescription;
        getApp()->getNormalFont()->getFontDesc(fontdescription);
        m_ircFont = new FXFont(getApp(),fontdescription);
        m_ircFont->create();
    }
    //set theme
    m_themeCurrent = m_preferences.m_appTheme;

    m_showImportwarning = TRUE;

    //General settings tab
    m_targetOneInstance.connect(m_preferences.m_oneInstance);
    m_targetDisableSortTabs.connect(m_preferences.m_disableSortTabs);
    m_targetReconnect.connect(m_preferences.m_reconnect);
    m_targetReconnect.setTarget(this);
    m_targetReconnect.setSelector(ConfigDialog_RECONNECT);
    m_targetNumberAttempt.connect(m_preferences.m_numberAttempt);
    m_targetDelayAttempt.connect(m_preferences.m_delayAttempt);
    m_targetMaxAway.connect(m_preferences.m_maxAway);
    m_targetUseTray.connect(m_preferences.m_useTray);
    m_targetUseTray.setTarget(this);
    m_targetUseTray.setSelector(ConfigDialog_TRAY);
    m_targetCloseToTray.connect(m_preferences.m_closeToTray);
    m_targetUseSpell.connect(m_preferences.m_useSpell);
    m_targetOwnServerWindow.connect(m_preferences.m_ownServerWindow);
    m_targetLogging.connect(m_preferences.m_logging);
    m_targetLogging.setTarget(this);
    m_targetLogging.setSelector(ConfigDialog_LOG);
    m_targetLogPath.connect(m_preferences.m_logPath);
    m_targetAutoload.connect(m_preferences.m_autoload);
    m_targetAutoload.setTarget(this);
    m_targetAutoload.setSelector(ConfigDialog_AUTOLOAD);
    m_targetAutoloadPath.connect(m_preferences.m_autoloadPath);

    //Look settings tab
    m_targetThemeBack.connect(m_themeCurrent.back);
    m_targetThemeBack.setTarget(this);
    m_targetThemeBack.setSelector(ConfigDialog_COLORS);
    m_targetThemeBase.connect(m_themeCurrent.base);
    m_targetThemeBase.setTarget(this);
    m_targetThemeBase.setSelector(ConfigDialog_COLORS);
    m_targetThemeBorder.connect(m_themeCurrent.border);
    m_targetThemeBorder.setTarget(this);
    m_targetThemeBorder.setSelector(ConfigDialog_COLORS);
    m_targetThemeFore.connect(m_themeCurrent.fore);
    m_targetThemeFore.setTarget(this);
    m_targetThemeFore.setSelector(ConfigDialog_COLORS);
    m_targetThemeMenuback.connect(m_themeCurrent.menuback);
    m_targetThemeMenuback.setTarget(this);
    m_targetThemeMenuback.setSelector(ConfigDialog_COLORS);
    m_targetThemeMenufore.connect(m_themeCurrent.menufore);
    m_targetThemeMenufore.setTarget(this);
    m_targetThemeMenufore.setSelector(ConfigDialog_COLORS);
    m_targetThemeSelback.connect(m_themeCurrent.selback);
    m_targetThemeSelback.setTarget(this);
    m_targetThemeSelback.setSelector(ConfigDialog_COLORS);
    m_targetThemeSelfore.connect(m_themeCurrent.selfore);
    m_targetThemeSelfore.setTarget(this);
    m_targetThemeSelfore.setSelector(ConfigDialog_COLORS);
    m_targetThemeTipback.connect(m_themeCurrent.tipback);
    m_targetThemeTipback.setTarget(this);
    m_targetThemeTipback.setSelector(ConfigDialog_COLORS);
    m_targetThemeTipfore.connect(m_themeCurrent.tipfore);
    m_targetThemeTipfore.setTarget(this);
    m_targetThemeTipfore.setSelector(ConfigDialog_COLORS);
	
    m_targetThemeNotifyback.connect(m_themeCurrent.notifyback);
    m_targetThemeNotifyback.setTarget(this);
    m_targetThemeNotifyback.setSelector(ConfigDialog_COLORS);
    m_targetThemeNotifyfore.connect(m_themeCurrent.notifyfore);
    m_targetThemeNotifyfore.setTarget(this);
    m_targetThemeNotifyfore.setSelector(ConfigDialog_COLORS);
    m_targetTrayColor.connect(m_preferences.m_trayColor);
    m_targetUnreadColor.connect(m_preferences.m_unreadColor);
    m_targetUnreadColor.setTarget(this);
    m_targetUnreadColor.setSelector(ConfigDialog_TABCOLORS);
    m_targetHighlightColor.connect(m_preferences.m_highlightColor);
    m_targetHighlightColor.setTarget(this);
    m_targetHighlightColor.setSelector(ConfigDialog_TABCOLORS);

    //Irc Text settings tab
    m_targetIrccolorsText.connect(m_preferences.m_colors.text);
    m_targetIrccolorsText.setTarget(this);
    m_targetIrccolorsText.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsBack.connect(m_preferences.m_colors.back);
    m_targetIrccolorsBack.setTarget(this);
    m_targetIrccolorsBack.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsUser.connect(m_preferences.m_colors.user);
    m_targetIrccolorsUser.setTarget(this);
    m_targetIrccolorsUser.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsAction.connect(m_preferences.m_colors.action);
    m_targetIrccolorsAction.setTarget(this);
    m_targetIrccolorsAction.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsNotice.connect(m_preferences.m_colors.notice);
    m_targetIrccolorsNotice.setTarget(this);
    m_targetIrccolorsNotice.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsError.connect(m_preferences.m_colors.error);
    m_targetIrccolorsError.setTarget(this);
    m_targetIrccolorsError.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsHilight.connect(m_preferences.m_colors.hilight);
    m_targetIrccolorsHilight.setTarget(this);
    m_targetIrccolorsHilight.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsLink.connect(m_preferences.m_colors.link);
    m_targetIrccolorsLink.setTarget(this);
    m_targetIrccolorsLink.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsMymsg.connect(m_preferences.m_colors.mymsg);
    m_targetIrccolorsMymsg.setTarget(this);
    m_targetIrccolorsMymsg.setSelector(ConfigDialog_IRCCOLORS);
    m_targetIrccolorsLog.connect(m_preferences.m_colors.log);
    m_targetIrccolorsLog.setTarget(this);
    m_targetIrccolorsLog.setSelector(ConfigDialog_IRCCOLORS);
    m_targetSameCmd.connect(m_preferences.m_sameCmd);
    m_targetSameList.connect(m_preferences.m_sameList);
    m_targetColoredNick.connect(m_preferences.m_coloredNick);
    m_targetStripColors.connect(m_preferences.m_stripColors);
    m_targetLoadLog.connect(m_preferences.m_loadLog);
    m_targetLoadLog.setTarget(this);
    m_targetLoadLog.setSelector(ConfigDialog_LOADLOG);
    m_targetLoadLine.connect(m_preferences.m_loadLines);

    //NickList settings tab
    m_targetSortUserMode.connect(m_preferences.m_sortUserMode);

    //DCC settings
    m_targetDccPath.connect(m_preferences.m_dccPath);
    FXRex rex("\\l");
    if(m_preferences.m_dccIP.empty() || m_preferences.m_dccIP.contains('.')!=3 || rex.match(m_preferences.m_dccIP))
    {
        m_dccIP1 = "";
        m_dccIP2 = "";
        m_dccIP3 = "";
        m_dccIP4 = "";
    }
    else
    {
        m_dccIP1 = m_preferences.m_dccIP.section('.',0);
        m_dccIP2 = m_preferences.m_dccIP.section('.',1);
        m_dccIP3 = m_preferences.m_dccIP.section('.',2);
        m_dccIP4 = m_preferences.m_dccIP.section('.',3);
    }
    m_targetDccIP1.connect(m_dccIP1);
    m_targetDccIP2.connect(m_dccIP2);
    m_targetDccIP3.connect(m_dccIP3);
    m_targetDccIP4.connect(m_dccIP4);
    m_targetDccPortD.connect(m_preferences.m_dccPortD);
    m_targetDccPortD.setTarget(this);
    m_targetDccPortD.setSelector(ConfigDialog_DCCPORTD);
    m_targetDccPortH.connect(m_preferences.m_dccPortH);
    m_targetDccPortH.setTarget(this);
    m_targetDccPortH.setSelector(ConfigDialog_DCCPORTH);
    m_targetDccTimeout.connect(m_preferences.m_dccTimeout);
    m_targetAutoDccChat.connect(m_preferences.m_autoDccChat);
    m_targetAutoDccFile.connect(m_preferences.m_autoDccFile);

    //Notification settings tab
    m_targetSound.connect(m_preferences.m_sounds);
    m_targetSound.setTarget(this);
    m_targetSound.setSelector(ConfigDialog_SOUNDS);
    m_targetSoundConnect.connect(m_preferences.m_soundConnect);
    m_targetSoundConnect.setTarget(this);
    m_targetSoundConnect.setSelector(ConfigDialog_SOUNDCONNECT);
    m_targetSoundDisconnect.connect(m_preferences.m_soundDisconnect);
    m_targetSoundDisconnect.setTarget(this);
    m_targetSoundDisconnect.setSelector(ConfigDialog_SOUNDDISCONNECT);
    m_targetSoundMessage.connect(m_preferences.m_soundMessage);
    m_targetSoundMessage.setTarget(this);
    m_targetSoundMessage.setSelector(ConfigDialog_SOUNDMESSAGE);
    m_targetPathConnect.connect(m_preferences.m_pathConnect);
    m_targetPathDisconnect.connect(m_preferences.m_pathDisconnect);
    m_targetPathMessage.connect(m_preferences.m_pathMessage);
    m_targetNotify.connect(m_preferences.m_notify);
    m_targetNotify.setTarget(this);
    m_targetNotify.setSelector(ConfigDialog_NOTIFY);
    m_targetNotifyConnect.connect(m_preferences.m_notifyConnect);
    m_targetNotifyDisconnect.connect(m_preferences.m_notifyDisconnect);
    m_targetNotifyMessage.connect(m_preferences.m_notifyMessage);

    //Smileys settings tab
    m_targetUseSmileys.connect(m_preferences.m_useSmileys);
    m_targetUseSmileys.setTarget(this);
    m_targetUseSmileys.setSelector(ConfigDialog_USESMILEYS);

    getApp()->getNormalFont()->create();
    FXFontDesc fontdescription;
    getApp()->getNormalFont()->getFontDesc(fontdescription);
    m_font = new FXFont(getApp(),fontdescription);
    m_font->create();

    FXHorizontalFrame *closeframe = new FXHorizontalFrame(this, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH);
    dxEXButton *ok = new dxEXButton(closeframe, _("&Save&&Close"), NULL, this, ConfigDialog_CLOSE, BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK, 0,0,0,0, 10,10,2,2);
    ok->addHotKey(KEY_Return);
    new dxEXButton(closeframe, _("&Cancel"), NULL, this, FXDialogBox::ID_CANCEL, LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK, 0,0,0,0, 10,10,2,2);

    FXVerticalFrame *contents = new FXVerticalFrame(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_tabbook = new dxTabBook(contents, this, ConfigDialog_TABS, PACK_UNIFORM_WIDTH|PACK_UNIFORM_HEIGHT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_tabbook->setTabStyle(TABBOOK_LEFTTABS);

    createGeneralTab(m_tabbook);
    createLookTab(m_tabbook);
    createIrctextTab(m_tabbook);
    createNicklistTab(m_tabbook);
    createIgnoreTab(m_tabbook);
    createDccTab(m_tabbook);
    createNotificationTab(m_tabbook);
    createSmileysTab(m_tabbook);
    createKeybindingsTab(m_tabbook);

    updateColors();
    updateFont();
    updateIrcFont();
}


ConfigDialog::~ConfigDialog()
{
    delete m_font;
    delete m_ircFont;
}

void ConfigDialog::createGeneralTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("&General"), NULL, TAB_LEFT);
    FXVerticalFrame *generalpane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    new FXCheckButton(generalpane, _("Run one instance"), &m_targetOneInstance, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new FXCheckButton(generalpane, _("Disable tabs sorting"), &m_targetDisableSortTabs, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new FXCheckButton(generalpane, _("Reconnect after disconnection"), &m_targetReconnect, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    FXHorizontalFrame *napane = new FXHorizontalFrame(generalpane, LAYOUT_FILL_X);
    m_numberAttemptLabel = new FXLabel(napane, _("Number of attempts (zero for unlimited)"), NULL, LAYOUT_LEFT);
    if(!m_preferences.m_reconnect) m_numberAttemptLabel->disable();
    m_numberAttemptSpinner = new FXSpinner(napane, 4, &m_targetNumberAttempt, FXDataTarget::ID_VALUE, SPIN_CYCLIC|FRAME_GROOVE);
    m_numberAttemptSpinner->setRange(0,20);
    if(!m_preferences.m_reconnect) m_numberAttemptSpinner->disable();
    FXHorizontalFrame *dapane = new FXHorizontalFrame(generalpane, LAYOUT_FILL_X);
    m_delayAttemptLabel = new FXLabel(dapane, _("Delay between two attempts in seconds"), NULL, LAYOUT_LEFT);
    if(!m_preferences.m_reconnect) m_delayAttemptLabel->disable();
    m_delayAttemptSpinner = new FXSpinner(dapane, 4, &m_targetDelayAttempt, FXDataTarget::ID_VALUE, SPIN_CYCLIC|FRAME_GROOVE);
    m_delayAttemptSpinner->setRange(5,120);
    if(!m_preferences.m_reconnect) m_delayAttemptSpinner->disable();
    FXHorizontalFrame *maxpane = new FXHorizontalFrame(generalpane, LAYOUT_FILL_X);
    new FXLabel(maxpane, _("Max. users number for checking away\tToo high number can be reason for ban"), NULL, LAYOUT_LEFT);
    new FXSpinner(maxpane, 4, &m_targetMaxAway, FXDataTarget::ID_VALUE, SPIN_NOMAX|FRAME_GROOVE);
#ifdef HAVE_TRAY
    new FXCheckButton(generalpane, _("Use trayicon"), &m_targetUseTray, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    m_closeToTrayButton = new FXCheckButton(generalpane, _("Close button hides application"), &m_targetCloseToTray, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_useTray) m_closeToTrayButton->disable();
#endif
#ifdef HAVE_ENCHANT
    FXCheckButton *spell = new FXCheckButton(generalpane, _("Use spellchecking"), &m_targetUseSpell, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!utils::instance().getAvailableSpellLangsNum())
    {
        spell->disable();
        m_preferences.m_useSpell = FALSE;
    }
    spell->setCheck(m_preferences.m_useSpell);
#endif
    new FXCheckButton(generalpane, _("Special tab for server messages"), &m_targetOwnServerWindow, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new FXCheckButton(generalpane, _("Logging chats"), &m_targetLogging, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    FXHorizontalFrame *logpane = new FXHorizontalFrame(generalpane, LAYOUT_FILL_X);
    new FXLabel(logpane, _("Log path"), NULL, LAYOUT_LEFT);
    (new FXTextField(logpane, 25, &m_targetLogPath, FXDataTarget::ID_VALUE, TEXTFIELD_READONLY|FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_X))->disable();
    if(!FXStat::exists(m_preferences.m_logPath)) m_preferences.m_logPath = FXSystem::getHomeDirectory();
    m_selectPath = new dxEXButton(logpane, "...", NULL, this, ConfigDialog_LOGPATH, FRAME_RAISED|FRAME_THICK);
    if(m_preferences.m_logging) m_selectPath->enable();
    else m_selectPath->disable();
#ifdef HAVE_LUA
    new FXCheckButton(generalpane, _("Automatically load scripts"), &m_targetAutoload, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    FXHorizontalFrame *aloadpane = new FXHorizontalFrame(generalpane, LAYOUT_FILL_X);
    new FXLabel(aloadpane, _("Path"), NULL, LAYOUT_LEFT);
    (new FXTextField(aloadpane, 25, &m_targetAutoloadPath, FXDataTarget::ID_VALUE, TEXTFIELD_READONLY|FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_X))->disable();
    if(!FXStat::exists(m_preferences.m_autoloadPath))
    {
#ifdef WIN32
        m_preferences.m_autoloadPath = utils::instance().localeToUtf8(FXSystem::getHomeDirectory()+PATHSEPSTRING+"scripts");
#else
        m_preferences.m_autoloadPath = FXSystem::getHomeDirectory()+PATHSEPSTRING+".dxirc"+PATHSEPSTRING+"scripts";
#endif
    }
    m_selectAutoloadPath = new dxEXButton(aloadpane, "...", NULL, this, ConfigDialog_AUTOLOADPATH, FRAME_RAISED|FRAME_THICK);
    if(m_preferences.m_autoload) m_selectAutoloadPath->enable();
    else m_selectAutoloadPath->disable();
#endif
}

void ConfigDialog::createLookTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("Loo&k"), NULL, TAB_LEFT);
    FXVerticalFrame *lookpane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXHorizontalFrame *hframe1 = new FXHorizontalFrame(lookpane, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXVerticalFrame *vframe1 = new FXVerticalFrame(hframe1, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_vframe2 = new FXVerticalFrame(hframe1, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_THICK|FRAME_RAISED);
    new FXLabel(vframe1, _("Theme:"), NULL, LAYOUT_CENTER_Y);
    m_themes = new FXListBox(vframe1,this,ConfigDialog_THEME,LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK);
    m_themes->setNumVisible(9);
    fillThemes();
    new FXSeparator(vframe1, SEPARATOR_GROOVE|LAYOUT_FILL_X);
    FXMatrix *themeMatrix = new FXMatrix(vframe1, 2, LAYOUT_FILL_Y|MATRIX_BY_COLUMNS, 0,0,0,0, DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING, 1,1);
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeBase, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Base Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeBorder, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Border Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeFore,FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Text Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeBack, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Background Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeSelfore, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Selected Text Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeSelback, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Selected Background Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeMenufore, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Selected Menu Text Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeMenuback, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Selected Menu Background Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeTipfore, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Tip Text Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeTipback, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Tip Background Color"));
#ifndef HAVE_LIBNOTIFY
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeNotifyfore, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Notify Text Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetThemeNotifyback, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Notify Background Color"));
#endif
#ifndef WIN32
#ifdef HAVE_TRAY
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetTrayColor, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Tray Color"));
#endif
#endif
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetUnreadColor, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Unreaded Tab Color"));
    new FXColorWell(themeMatrix, FXRGB(0,0,255), &m_targetHighlightColor, FXDataTarget::ID_VALUE);
    new FXLabel(themeMatrix, _("Highlighted Tab Color"));
    FXHorizontalFrame *tabpane = new FXHorizontalFrame(vframe1, LAYOUT_FILL_X);
    new FXLabel(tabpane, _("Tab position"), NULL, LAYOUT_LEFT);
    m_listTabs = new FXListBox(tabpane, this, ConfigDialog_TABPOS);
    m_listTabs->appendItem(_("Bottom"));
    m_listTabs->appendItem(_("Left"));
    m_listTabs->appendItem(_("Top"));
    m_listTabs->appendItem(_("Right"));
    m_listTabs->setNumVisible(4);
    if(m_preferences.m_tabPosition>=0 && m_preferences.m_tabPosition<4) m_listTabs->setCurrentItem(m_preferences.m_tabPosition);
    m_label = new FXLabel(m_vframe2, "Label");
    m_textFrame1 = new FXHorizontalFrame(m_vframe2, LAYOUT_FILL_X);
    m_textTest = new FXTextField(m_textFrame1, 30, NULL, 0, LAYOUT_FILL_X|FRAME_THICK|FRAME_SUNKEN);
    m_textTest->setText(_("Select this text, to see the selected colors"));
    m_textFrame2 = new FXHorizontalFrame(m_vframe2, LAYOUT_FILL_X|FRAME_THICK|FRAME_SUNKEN, 0,0,0,0,2,2,2,2,0,0);
    m_labelSelected = new FXLabel(m_textFrame2, _("Selected Text (with focus)"), NULL, LAYOUT_FILL_X, 0,0,0,0,1,1,1,1);
    m_textFrame3 = new FXHorizontalFrame(m_vframe2, LAYOUT_FILL_X|FRAME_THICK|FRAME_SUNKEN, 0,0,0,0,2,2,2,2,0,0);
    m_labelNocurrent = new FXLabel(m_textFrame3, _("Selected Text (no focus)"), NULL, LAYOUT_FILL_X, 0,0,0,0,1,1,1,1);
    m_sep1 = new FXSeparator(m_vframe2, LAYOUT_FILL_X|SEPARATOR_LINE);
    m_labelTip = new FXLabel(m_vframe2, _("Tooltip example"), NULL, FRAME_LINE|LAYOUT_CENTER_X);
    m_menuGroup = new FXGroupBox(m_vframe2, _("Menu example"), FRAME_GROOVE|LAYOUT_FILL_Y|LAYOUT_FILL_X);
    m_menuFrame = new FXVerticalFrame(m_menuGroup, FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_X|LAYOUT_CENTER_Y, 0,0,0,0,0,0,0,0,0,0);
    m_menuLabels[0] = new FXLabel(m_menuFrame, _("&Server list"), NULL, LABEL_NORMAL, 0,0,0,0,16,4);
    m_menuLabels[1] = new FXLabel(m_menuFrame, _("Selected Menu Entry"), NULL, LABEL_NORMAL, 0,0,0,0,16,4);
    m_sep2 = new FXSeparator(m_menuFrame, LAYOUT_FILL_X|SEPARATOR_LINE);
    m_menuLabels[2]=new FXLabel(m_menuFrame, _("&Quit"), NULL, LABEL_NORMAL, 0,0,0,0,16,4);
#ifndef HAVE_LIBNOTIFY
    m_labelNotify = new FXLabel(m_vframe2, _("Notify example"), ICO_BIG, FRAME_LINE|LAYOUT_CENTER_X|ICON_BEFORE_TEXT);
#endif
    m_tabFrame = new FXHorizontalFrame(m_vframe2, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_tabs = new dxTabBook(m_tabFrame, NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_tab = new dxEXTabItem(m_tabs, "#abc", ICO_CHANNEL);
    m_tabframe1 = new FXVerticalFrame(m_tabs, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_tabLabel1 = new FXLabel(m_tabframe1, _("Standard tab"));
    m_unread = new dxEXTabItem(m_tabs, "#def", ICO_CHANNEL);
    m_tabframe2 = new FXVerticalFrame(m_tabs, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_tabLabel2 = new FXLabel(m_tabframe2, _("Unreaded tab"));
    m_highlight = new dxEXTabItem(m_tabs, "#ghi", ICO_CHANNELNEWMSG);
    m_tabframe3 = new FXVerticalFrame(m_tabs, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_tabLabel3 = new FXLabel(m_tabframe3, _("Highlighted tab"));
    updateTabPosition();
    FXHorizontalFrame *fontframe = new FXHorizontalFrame(lookpane, LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING);
    new FXLabel(fontframe, _("Font"));
    m_fontButton = new dxEXButton(fontframe, " ", NULL, this, ConfigDialog_FONT, LAYOUT_CENTER_Y|FRAME_RAISED|JUSTIFY_CENTER_X|JUSTIFY_CENTER_Y|LAYOUT_FILL_X);
}

void ConfigDialog::createIrctextTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("&Irc Text"), NULL, TAB_LEFT);
    FXVerticalFrame *irctextpane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXHorizontalFrame *hframe = new FXHorizontalFrame(irctextpane, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXVerticalFrame *cframe = new FXVerticalFrame(hframe, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXMatrix *colormatrix = new FXMatrix(cframe, 2, MATRIX_BY_COLUMNS, 0,0,0,0, DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING, 1,1);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsBack, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Text backround color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsText, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Text color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsUser, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("User events text color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsAction, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Actions message text color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsNotice, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Notice text color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsError, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Error text color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsHilight, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Highlight message text color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsLink, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Link color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsMymsg, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("My message color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXColorWell(colormatrix, FXRGB(0,0,255), &m_targetIrccolorsLog, FXDataTarget::ID_VALUE, COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW, 0,0,40,24);
    new FXLabel(colormatrix, _("Log line color"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXLabel(colormatrix, _("Font"));
    m_ircfontButton = new dxEXButton(colormatrix, " ", NULL, this, ConfigDialog_IRCFONT, LAYOUT_CENTER_Y|FRAME_RAISED|JUSTIFY_CENTER_X|JUSTIFY_CENTER_Y|LAYOUT_FILL_X, 0,0,0,0, 10,10,2,2);
    FXHorizontalFrame *nickpane = new FXHorizontalFrame(cframe, LAYOUT_FILL_X);
    new FXLabel(nickpane, _("Nick completion char"), NULL, LAYOUT_LEFT);
    m_nickCharField = new FXTextField(nickpane, 1, this, ConfigDialog_NICK, TEXTFIELD_LIMITED|FRAME_THICK|FRAME_SUNKEN/*|LAYOUT_FILL_X*/);
    m_nickCharField->setText(m_preferences.m_nickCompletionChar);
    new FXCheckButton(cframe, _("Use same font for commandline"), &m_targetSameCmd, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new FXCheckButton(cframe, _("Use same font for user list"), &m_targetSameList, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new FXCheckButton(cframe, _("Use colored nick"), &m_targetColoredNick, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new FXCheckButton(cframe, _("Strip colors in text"), &m_targetStripColors, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    m_loadLogButton = new FXCheckButton(cframe, _("Load logged lines"), &m_targetLoadLog, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_logging) m_loadLogButton->disable();
    FXHorizontalFrame *linepane = new FXHorizontalFrame(cframe, LAYOUT_FILL_X);
    new FXLabel(linepane, _("Load max. number lines"), NULL, LAYOUT_LEFT);
    m_loadLineSpinner = new FXSpinner(linepane, 4, &m_targetLoadLine, FXDataTarget::ID_VALUE, SPIN_NOMAX|FRAME_GROOVE);
    if(!m_preferences.m_logging || !m_preferences.m_loadLog) m_loadLineSpinner->disable();
    FXVerticalFrame *tframe = new FXVerticalFrame(hframe, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_text = new FXText(tframe, NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_READONLY);
    m_text->setScrollStyle(HSCROLLING_OFF);
    for(int i=0; i<8; i++)
    {
        m_textStyle[i].normalForeColor = m_preferences.m_colors.text;
        m_textStyle[i].normalBackColor = m_preferences.m_colors.back;
        m_textStyle[i].selectForeColor = getApp()->getSelforeColor();
        m_textStyle[i].selectBackColor = getApp()->getSelbackColor();
        m_textStyle[i].hiliteForeColor = getApp()->getHiliteColor();
        m_textStyle[i].hiliteBackColor = FXRGB(255, 128, 128); // from FXText.cpp
        m_textStyle[i].activeBackColor = m_preferences.m_colors.back;
        m_textStyle[i].style = 0;
    }
    //user commands
    m_textStyle[0].normalForeColor = m_preferences.m_colors.user;
    //Actions
    m_textStyle[1].normalForeColor = m_preferences.m_colors.action;
    //Notice
    m_textStyle[2].normalForeColor = m_preferences.m_colors.notice;
    //Errors
    m_textStyle[3].normalForeColor = m_preferences.m_colors.error;
    //Highlight
    m_textStyle[4].normalForeColor = m_preferences.m_colors.hilight;
    //link
    m_textStyle[5].normalForeColor = m_preferences.m_colors.link;
    m_textStyle[5].style = FXText::STYLE_UNDERLINE;
    //My message
    m_textStyle[6].normalForeColor = m_preferences.m_colors.mymsg;
    //Log line
    m_textStyle[7].normalForeColor = m_preferences.m_colors.log;
    m_text->setStyled(TRUE);
    m_text->setHiliteStyles(m_textStyle);
    m_text->setTextColor(m_preferences.m_colors.text);
    m_text->setBackColor(m_preferences.m_colors.back);
    m_text->appendStyledText(FXString("[24.12.2008 00:08:00] dvx: dxirc 0.10.0\n"), 8);
    m_text->appendText("[00:00:00] ");
    m_text->appendStyledText(FXString("dvx has joined to #dxirc\n"), 1);
    m_text->appendText("[00:00:00] ");
    m_text->appendStyledText(FXString("dvx: Welcome in dxirc\n"), 7);
    m_text->appendText("[00:00:00] ");
    m_text->appendStyledText(FXString("bm: dvx, dxirc is nice\n"), 5);
    m_text->appendText("[00:00:00] ");
    m_text->appendStyledText(FXString("dvx is online\n"), 2);
    m_text->appendText("[00:00:00] ");
    m_text->appendStyledText(FXString("server's NOTICE: nice notice\n"), 3);
    m_text->appendText("[00:00:00] ");
    m_text->appendStyledText(FXString("No error\n"), 4);
    m_text->appendText("[00:00:00] ");
    m_text->appendStyledText(FXString("dvx: "), 7);
    m_text->appendStyledText(FXString("http://dxirc.org"), 6);
}

void ConfigDialog::createNicklistTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("Nick &list"), NULL, TAB_LEFT);
    FXVerticalFrame *nicklistpane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXGroupBox *themesgroup = new FXGroupBox(nicklistpane, _("Icons themes"), FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_SIDE_TOP);
    FXVerticalFrame *themesbuttons = new FXVerticalFrame(themesgroup, LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    m_addTheme = new dxEXButton(themesbuttons, _("Add"), NULL, this, ConfigDialog_ADDICONS, FRAME_RAISED|FRAME_THICK);
    m_deleteTheme = new dxEXButton(themesbuttons, _("Delete"), NULL, this, ConfigDialog_DELETEICONS, FRAME_RAISED|FRAME_THICK);
    FXVerticalFrame *themeslist = new FXVerticalFrame(themesgroup, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK);
    m_icons = new FXList(themeslist, this, ConfigDialog_ICONS, LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    fillIcons();
    for(FXint i=0; i<m_icons->getNumItems(); i++)
    {
        if(m_icons->getItemText(i) == m_preferences.m_themePath)
        {
            m_icons->setCurrentItem(i);
            break;
        }
    }
    m_icons->getNumItems()>1 ? m_deleteTheme->enable() : m_deleteTheme->disable();
    FXMatrix *iconmatrix = new FXMatrix(themeslist, 2, MATRIX_BY_COLUMNS, 0,0,0,0, DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING, 1,1);
    new FXLabel(iconmatrix, _("Admin:"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    m_icon1 = new FXLabel(iconmatrix, "", NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXLabel(iconmatrix, _("Owner:"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    m_icon2 = new FXLabel(iconmatrix, "", NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXLabel(iconmatrix, _("Op:"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    m_icon3 = new FXLabel(iconmatrix, "", NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXLabel(iconmatrix, _("Halfop:"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    m_icon4 = new FXLabel(iconmatrix, "", NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXLabel(iconmatrix, _("Voice:"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    m_icon5 = new FXLabel(iconmatrix, "", NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXLabel(iconmatrix, _("Normal:"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    m_icon6 = new FXLabel(iconmatrix, "", NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    new FXLabel(iconmatrix, _("Away:"), NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    m_icon7 = new FXLabel(iconmatrix, "", NULL, JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW);
    updateNickIcons();
    new FXCheckButton(nicklistpane, _("Sort nick list by user mode"), &m_targetSortUserMode, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
}

void ConfigDialog::createIgnoreTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("Ig&nore"), NULL, TAB_LEFT);
    FXVerticalFrame *ignorepane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXGroupBox *commandsgroup = new FXGroupBox(ignorepane, _("Commands"), FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_SIDE_TOP);
    FXVerticalFrame *commandsbuttons = new FXVerticalFrame(commandsgroup, LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    m_addCommand = new dxEXButton(commandsbuttons, _("Add"), NULL, this, ConfigDialog_ADDCOMMAND, FRAME_RAISED|FRAME_THICK);
    m_deleteCommand = new dxEXButton(commandsbuttons, _("Delete"), NULL, this, ConfigDialog_DELETECOMMAND, FRAME_RAISED|FRAME_THICK);
    FXVerticalFrame *commandslist = new FXVerticalFrame(commandsgroup, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK);
    m_commands = new FXList(commandslist, this, ConfigDialog_COMMAND, LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXGroupBox *usersgroup = new FXGroupBox(ignorepane, _("Users"), FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXVerticalFrame *usersbuttons = new FXVerticalFrame(usersgroup, LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    m_addUser = new dxEXButton(usersbuttons, _("Add"), NULL, this, ConfigDialog_ADDUSER, FRAME_RAISED|FRAME_THICK);
    m_modifyUser = new dxEXButton(usersbuttons, _("Modify"), NULL, this, ConfigDialog_MODIFYUSER, FRAME_RAISED|FRAME_THICK);
    m_deleteUser = new dxEXButton(usersbuttons, _("Delete"), NULL, this, ConfigDialog_DELETEUSER, FRAME_RAISED|FRAME_THICK);
    FXVerticalFrame *userspane = new FXVerticalFrame(usersgroup, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK);
    FXHorizontalFrame *usersframe = new FXHorizontalFrame(userspane, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_users = new FXIconList(usersframe, this, ConfigDialog_USER, ICONLIST_AUTOSIZE|ICONLIST_DETAILED|ICONLIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_users->appendHeader(_("User"), NULL, 200);
    m_users->appendHeader(_("Channel(s)"), NULL, 150);
    m_users->appendHeader(_("Network"), NULL, 150);
    fillCommnads();
    fillUsers();
    m_commands->getNumItems() ? m_deleteCommand->enable() : m_deleteCommand->disable();
    if(m_preferences.m_ignoreUsersList.no())
    {
        m_deleteUser->enable();
        m_modifyUser->enable();
    }
    else
    {
        m_deleteUser->disable();
        m_modifyUser->disable();
    }
}

void ConfigDialog::createDccTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("&DCC"), NULL, TAB_LEFT);
    FXVerticalFrame *dccpane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    new FXLabel(dccpane, _("Directory for saving files:"), NULL, LAYOUT_LEFT);
    FXHorizontalFrame *pathframe = new FXHorizontalFrame(dccpane, LAYOUT_FILL_X);
    (new FXTextField(pathframe, 30, &m_targetDccPath, FXDataTarget::ID_VALUE, TEXTFIELD_READONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X))->disable();
    new dxEXButton(pathframe, "...", NULL, this, ConfigDialog_DCCPATH, FRAME_RAISED|FRAME_THICK);
    FXHorizontalFrame *ipframe = new FXHorizontalFrame(dccpane, LAYOUT_FILL_X);
    new FXLabel(ipframe, _("DCC IP address:"), NULL, LAYOUT_LEFT);
    new FXTextField(ipframe, 3, &m_targetDccIP1, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER|TEXTFIELD_LIMITED|FRAME_SUNKEN|FRAME_THICK);
    new FXLabel(ipframe, ".", NULL, LAYOUT_LEFT);
    new FXTextField(ipframe, 3, &m_targetDccIP2, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER|TEXTFIELD_LIMITED|FRAME_SUNKEN|FRAME_THICK);
    new FXLabel(ipframe, ".", NULL, LAYOUT_LEFT);
    new FXTextField(ipframe, 3, &m_targetDccIP3, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER|TEXTFIELD_LIMITED|FRAME_SUNKEN|FRAME_THICK);
    new FXLabel(ipframe, ".", NULL, LAYOUT_LEFT);
    new FXTextField(ipframe, 3, &m_targetDccIP4, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER|TEXTFIELD_LIMITED|FRAME_SUNKEN|FRAME_THICK);
    new FXLabel(dccpane, _("(Leave blank for use IP address from server)"), NULL, LAYOUT_LEFT);
    new FXSeparator(dccpane, LAYOUT_FILL_X);
    FXHorizontalFrame *portframe = new FXHorizontalFrame(dccpane, LAYOUT_FILL_X);
    new FXLabel(portframe, _("DCC ports:"), NULL, LAYOUT_LEFT);
    FXSpinner *dspinner = new FXSpinner(portframe, 6, &m_targetDccPortD, FXDataTarget::ID_VALUE, FRAME_SUNKEN|FRAME_THICK);
    dspinner->setRange(0, 65536);
    new FXLabel(portframe, "-");
    FXSpinner *hspinner = new FXSpinner(portframe, 6, &m_targetDccPortH, FXDataTarget::ID_VALUE, FRAME_SUNKEN|FRAME_THICK);
    hspinner->setRange(0, 65536);
    new FXLabel(dccpane, _("(Set 0 for use ports from OS)"), NULL, LAYOUT_LEFT);
    FXHorizontalFrame *timeframe = new FXHorizontalFrame(dccpane, LAYOUT_FILL_X);
    new FXLabel(timeframe, _("Time for waiting for connection in seconds"), NULL, LAYOUT_LEFT);
    new FXSpinner(timeframe, 4, &m_targetDccTimeout, FXDataTarget::ID_VALUE, SPIN_NOMAX|SPIN_CYCLIC|FRAME_SUNKEN|FRAME_THICK);
    new FXCheckButton(dccpane, _("Automatically connect offered chat"), &m_targetAutoDccChat, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new FXCheckButton(dccpane, _("Automatically receive offered file"), &m_targetAutoDccFile, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
}

void ConfigDialog::createNotificationTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("N&otification"), NULL, TAB_LEFT);
    FXVerticalFrame *notificationpane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXGroupBox *friendsgroup = new FXGroupBox(notificationpane, _("Friends"), FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXVerticalFrame *friendsbuttons = new FXVerticalFrame(friendsgroup, LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    m_addFriend = new dxEXButton(friendsbuttons, _("Add"), NULL, this, ConfigDialog_ADDFRIEND, FRAME_RAISED|FRAME_THICK);
    m_modifyFriend = new dxEXButton(friendsbuttons, _("Modify"), NULL, this, ConfigDialog_MODIFYFRIEND, FRAME_RAISED|FRAME_THICK);
    m_deleteFriend = new dxEXButton(friendsbuttons, _("Delete"), NULL, this, ConfigDialog_DELETEFRIEND, FRAME_RAISED|FRAME_THICK);
    FXVerticalFrame *friendspane = new FXVerticalFrame(friendsgroup, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK);
    FXHorizontalFrame *friendsframe = new FXHorizontalFrame(friendspane, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_friends = new FXIconList(friendsframe, this, ConfigDialog_FRIEND, ICONLIST_AUTOSIZE|ICONLIST_DETAILED|ICONLIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_friends->appendHeader(_("Friend"), NULL, 150);
    m_friends->appendHeader(_("Channel(s)"), NULL, 150);
    m_friends->appendHeader(_("Network"), NULL, 150);
    fillFriends();
    if(m_preferences.m_friendsList.no())
    {
        m_deleteFriend->enable();
        m_modifyFriend->enable();
    }
    else
    {
        m_deleteFriend->disable();
        m_modifyFriend->disable();
    }
    new FXCheckButton(notificationpane, _("Use sounds"), &m_targetSound, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    FXGroupBox *eventsgroup = new FXGroupBox(notificationpane, _("Events"), FRAME_GROOVE|LAYOUT_FILL_X);
    FXVerticalFrame *eventsframe = new FXVerticalFrame(eventsgroup, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_checkConnect = new FXCheckButton(eventsframe, _("Friend connected"), &m_targetSoundConnect, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_sounds)
        m_checkConnect->disable();
    FXHorizontalFrame *connectframe = new FXHorizontalFrame(eventsframe, LAYOUT_FILL_X|PACK_UNIFORM_HEIGHT);
    (new FXTextField(connectframe, 30, &m_targetPathConnect, FXDataTarget::ID_VALUE, TEXTFIELD_READONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X))->disable();
    m_selectConnect = new dxEXButton(connectframe, "...", NULL, this, ConfigDialog_SELECTCONNECT, FRAME_RAISED|FRAME_THICK);
    m_playConnect = new dxEXButton(connectframe, _("\tPlay"), ICO_PLAY, this, ConfigDialog_PLAYCONNECT, FRAME_RAISED|FRAME_THICK);
    if(!m_preferences.m_soundConnect || !m_preferences.m_sounds)
    {
        m_selectConnect->disable();
        m_playConnect->disable();
    }
    if(!FXStat::exists(m_preferences.m_pathConnect))
        m_playConnect->disable();
    m_checkDisconnect = new FXCheckButton(eventsframe, _("Friend disconnected"), &m_targetSoundDisconnect, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_sounds)
        m_checkDisconnect->disable();
    FXHorizontalFrame *disconnectframe = new FXHorizontalFrame(eventsframe, LAYOUT_FILL_X|PACK_UNIFORM_HEIGHT);
    (new FXTextField(disconnectframe, 30, &m_targetPathDisconnect, FXDataTarget::ID_VALUE, TEXTFIELD_READONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X))->disable();
    m_selectDisconnect = new dxEXButton(disconnectframe, "...", NULL, this, ConfigDialog_SELECTDISCONNECT, FRAME_RAISED|FRAME_THICK);
    m_playDisconnect = new dxEXButton(disconnectframe, _("\tPlay"), ICO_PLAY, this, ConfigDialog_PLAYDISCONNECT, FRAME_RAISED|FRAME_THICK);
    if(!m_preferences.m_soundDisconnect || !m_preferences.m_sounds)
    {
        m_selectDisconnect->disable();
        m_playDisconnect->disable();
    }
    if(!FXStat::exists(m_preferences.m_pathDisconnect))
        m_playDisconnect->disable();
    m_checkMessage = new FXCheckButton(eventsframe, _("Highlighted message or query message"), &m_targetSoundMessage, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_sounds)
        m_checkMessage->disable();
    FXHorizontalFrame *messageframe = new FXHorizontalFrame(eventsframe, LAYOUT_FILL_X|PACK_UNIFORM_HEIGHT);
    (new FXTextField(messageframe, 30, &m_targetPathMessage, FXDataTarget::ID_VALUE, TEXTFIELD_READONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X))->disable();
    m_selectMessage = new dxEXButton(messageframe, "...", NULL, this, ConfigDialog_SELECTMESSAGE, FRAME_RAISED|FRAME_THICK);
    m_playMessage = new dxEXButton(messageframe, _("\tPlay"), ICO_PLAY, this, ConfigDialog_PLAYMESSAGE, FRAME_RAISED|FRAME_THICK);
    if(!m_preferences.m_soundMessage || !m_preferences.m_sounds)
    {
        m_selectMessage->disable();
        m_playMessage->disable();
    }
    if(!FXStat::exists(m_preferences.m_pathMessage))
        m_playMessage->disable();
    FXHorizontalFrame *notifyframe = new FXHorizontalFrame(notificationpane, LAYOUT_FILL_X|PACK_UNIFORM_HEIGHT);
    new FXCheckButton(notifyframe, _("Use notify popup"), &m_targetNotify, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    new dxEXButton(notifyframe, _("Show"), NULL, this, ConfigDialog_SHOWNOTIFY, FRAME_RAISED|FRAME_THICK|LAYOUT_SIDE_LEFT);
#ifndef HAVE_LIBNOTIFY
    FXHorizontalFrame *notifyposframe = new FXHorizontalFrame(notificationpane, LAYOUT_FILL_X|PACK_UNIFORM_HEIGHT);
    new FXLabel(notifyposframe, _("Notify position"), NULL, LAYOUT_LEFT);
    m_listNotifyPos = new FXListBox(notifyposframe, this, ConfigDialog_NOTIFYPOS);
    m_listNotifyPos->appendItem(_("Left Top"));
    m_listNotifyPos->appendItem(_("Right Top"));
    m_listNotifyPos->appendItem(_("Left Bottom"));
    m_listNotifyPos->appendItem(_("Right Bottom"));
    m_listNotifyPos->setNumVisible(4);
    if(m_preferences.m_notifyPosition>=0 && m_preferences.m_notifyPosition<4) m_listNotifyPos->setCurrentItem(m_preferences.m_notifyPosition);
#endif
    FXGroupBox *neventsgroup = new FXGroupBox(notificationpane, _("Events"), FRAME_GROOVE|LAYOUT_FILL_X);
    FXVerticalFrame *neventsframe = new FXVerticalFrame(neventsgroup, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_checkNotifyConnect = new FXCheckButton(neventsframe, _("Friend connected"), &m_targetNotifyConnect, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_notify)
        m_checkNotifyConnect->disable();
    m_checkNotifyDisconnect = new FXCheckButton(neventsframe, _("Friend disconnected"), &m_targetNotifyDisconnect, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_notify)
        m_checkNotifyDisconnect->disable();
    m_checkNotifyMessage = new FXCheckButton(neventsframe, _("Highlighted message or query message"), &m_targetNotifyMessage, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    if(!m_preferences.m_notify)
        m_checkNotifyMessage->disable();
    if(!m_preferences.m_sounds && !m_preferences.m_notify)
    {
        m_addFriend->disable();
        m_deleteFriend->disable();
        m_modifyFriend->disable();
    }
}

void ConfigDialog::createSmileysTab(dxTabBook *tabbook)
{
    new dxEXTabItem(tabbook, _("S&mileys"), NULL, TAB_LEFT);
    FXVerticalFrame *smileypane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    new FXCheckButton(smileypane, _("Use smileys"), &m_targetUseSmileys, FXDataTarget::ID_VALUE, CHECKBUTTON_NORMAL|LAYOUT_FILL_X|LAYOUT_SIDE_LEFT|JUSTIFY_LEFT);
    FXGroupBox *smileysgroup = new FXGroupBox(smileypane, _("Smileys"), FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXVerticalFrame *smileysbuttons = new FXVerticalFrame(smileysgroup, LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    m_addSmiley = new dxEXButton(smileysbuttons, _("Add"), NULL, this, ConfigDialog_ADDSMILEY, FRAME_RAISED|FRAME_THICK);
    m_modifySmiley = new dxEXButton(smileysbuttons, _("Modify"), NULL, this, ConfigDialog_MODIFYSMILEY, FRAME_RAISED|FRAME_THICK);
    m_deleteSmiley = new dxEXButton(smileysbuttons, _("Delete"), NULL, this, ConfigDialog_DELETESMILEY, FRAME_RAISED|FRAME_THICK);
    m_importSmiley = new dxEXButton(smileysbuttons, _("Import"), NULL, this, ConfigDialog_IMPORTSMILEY, FRAME_RAISED|FRAME_THICK);
    m_exportSmiley = new dxEXButton(smileysbuttons, _("Export"), NULL, this, ConfigDialog_EXPORTSMILEY, FRAME_RAISED|FRAME_THICK);
    if(m_preferences.m_useSmileys)
    {
        m_addSmiley->enable();
        m_importSmiley->enable();
        if((FXint)m_preferences.m_smileysMap.size())
        {
            m_modifySmiley->enable();
            m_deleteSmiley->enable();
            m_exportSmiley->enable();
        }
        else
        {
            m_modifySmiley->disable();
            m_deleteSmiley->disable();
            m_exportSmiley->disable();
        }
    }
    else
    {
        m_addSmiley->disable();
        m_modifySmiley->disable();
        m_deleteSmiley->disable();
        m_importSmiley->disable();
        m_exportSmiley->disable();
    }
    FXVerticalFrame *smileyspane = new FXVerticalFrame(smileysgroup, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK);
    FXHorizontalFrame *smileysframe = new FXHorizontalFrame(smileyspane, LAYOUT_FILL_X|LAYOUT_FILL_Y);
    m_smileys = new FXList(smileysframe, this, ConfigDialog_SMILEY, LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    fillSmileys();
}

void ConfigDialog::createKeybindingsTab(dxTabBook* tabbook)
{
    new dxEXTabItem(tabbook, _("Key&bindings"), NULL, TAB_LEFT);
    FXVerticalFrame *kbpane = new FXVerticalFrame(tabbook, FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
    FXPacker *kbpack = new FXPacker(kbpane, LAYOUT_FILL_X);
    new dxEXButton(kbpack, _("Modify key bindings..."), ICO_KEYBINDINGS, this, ConfigDialog_MODIFYBINDINGS, FRAME_RAISED|FRAME_THICK|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
    new dxEXButton(kbpack, _("Restore default key bindings..."), ICO_REFRESH, this, ConfigDialog_REFRESHBINDINGS, FRAME_RAISED|FRAME_THICK|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
}

long ConfigDialog::onCommandsSelected(FXObject*, FXSelector, void*)
{
    m_deleteCommand->enable();
    return 1;
}

long ConfigDialog::onCommandsDeselected(FXObject*, FXSelector, void*)
{
    m_deleteCommand->disable();
    return 1;
}

long ConfigDialog::onUsersSelected(FXObject*, FXSelector, void *ptr)
{
    FXint i = (FXint)(FXival)ptr;
    m_users->selectItem(i);
    m_deleteUser->enable();
    return 1;
}

long ConfigDialog::onUsersDeselected(FXObject*, FXSelector, void*)
{
    m_deleteUser->disable();
    return 1;
}

long ConfigDialog::onUsersChanged(FXObject*, FXSelector, void *ptr)
{
    FXint i = (FXint)(FXival)ptr;
    m_users->selectItem(i);
    return 1;
}

long ConfigDialog::onFriendsSelected(FXObject*, FXSelector, void *ptr)
{
    FXint i = (FXint)(FXival)ptr;
    m_friends->selectItem(i);
    m_deleteFriend->enable();
    return 1;
}

long ConfigDialog::onFriendsDeselected(FXObject*, FXSelector, void*)
{
    m_deleteFriend->disable();
    return 1;
}

long ConfigDialog::onFriendsChanged(FXObject*, FXSelector, void *ptr)
{
    FXint i = (FXint)(FXival)ptr;
    m_friends->selectItem(i);
    return 1;
}

long ConfigDialog::onColor(FXObject*, FXSelector, void*)
{
    m_text->setTextColor(m_preferences.m_colors.text);
    m_text->setBackColor(m_preferences.m_colors.back);
    for(int i=0; i<8; i++)
    {
        m_textStyle[i].normalBackColor = m_preferences.m_colors.back;
    }
    m_textStyle[0].normalForeColor = m_preferences.m_colors.user;
    m_textStyle[1].normalForeColor = m_preferences.m_colors.action;
    m_textStyle[2].normalForeColor = m_preferences.m_colors.notice;
    m_textStyle[3].normalForeColor = m_preferences.m_colors.error;
    m_textStyle[4].normalForeColor = m_preferences.m_colors.hilight;
    m_textStyle[5].normalForeColor = m_preferences.m_colors.link;
    m_textStyle[6].normalForeColor = m_preferences.m_colors.mymsg;
    m_textStyle[7].normalForeColor = m_preferences.m_colors.log;
    m_text->update();
    return 1;
}

long ConfigDialog::onTabPosition(FX::FXObject *, FX::FXSelector, void *ptr)
{
    m_preferences.m_tabPosition = (FXint)(FXival)ptr;
    updateTabPosition();
    return 1;
}

long ConfigDialog::onNotifyPosition(FX::FXObject *, FX::FXSelector, void *ptr)
{
    m_preferences.m_notifyPosition = (FXint)(FXival)ptr;
    return 1;
}

long ConfigDialog::onClose(FXObject*, FXSelector, void*)
{
    getApp()->stopModal(this,TRUE);
    m_preferences.m_appTheme = m_themeCurrent;
    m_preferences.m_dccIP = m_dccIP1+"."+m_dccIP2+"."+m_dccIP3+"."+m_dccIP4;
    m_preferences.m_font = m_font->getFont();
    m_preferences.m_ircFont = m_ircFont->getFont();
    preferences = m_preferences;
    hide();
    return 1;
}

long ConfigDialog::onAddCommand(FXObject*, FXSelector, void*)
{
    FXDialogBox dialog(this, _("Select ignore command"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
    FXVerticalFrame *contents = new FXVerticalFrame(&dialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
    FXMatrix *matrix = new FXMatrix(contents,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);

    new FXLabel(matrix, _("Command:"),NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXComboBox *command = new FXComboBox(matrix, 1, NULL, 0, COMBOBOX_STATIC|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|FRAME_GROOVE);
    command->fillItems(fillCommandsCombo());

    FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    new dxEXButton(buttonframe, _("&Cancel"), NULL, &dialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
    new dxEXButton(buttonframe, _("&OK"), NULL, &dialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);

    if(dialog.execute(PLACEMENT_CURSOR))
    {
        m_commands->appendItem(command->getItemText(command->getCurrentItem()));
    }
    updateCommands();
    return 1;
}

long ConfigDialog::onDeleteCommand(FXObject*, FXSelector, void*)
{
    FXint i = m_commands->getCurrentItem();
    m_commands->removeItem(i);
    m_commands->getNumItems() ? m_deleteCommand->enable() : m_deleteCommand->disable();
    updateCommands();
    return 1;
}

long ConfigDialog::onAddUser(FXObject*, FXSelector, void*)
{
    FXDialogBox dialog(this, _("Add ignore user"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
    FXVerticalFrame *contents = new FXVerticalFrame(&dialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
    FXMatrix *matrix = new FXMatrix(contents,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);

    new FXLabel(matrix, _("Nick:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *nick = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    nick->setText("_example!example@example.com");
    new FXLabel(matrix, _("Channel(s):\tChannels need to be comma separated"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *channel = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    channel->setText("all");
    channel->setTipText(_("Channels need to be comma separated"));
    new FXLabel(matrix, _("Network:"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *network = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    network->setText("all");

    FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    new dxEXButton(buttonframe, _("&Cancel"), NULL, &dialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
    new dxEXButton(buttonframe, _("&OK"), NULL, &dialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);

    if(dialog.execute(PLACEMENT_CURSOR))
    {
        if(!nick->getText().empty() && !nickExist(nick->getText()))
        {
            UserInfo user;
            user.nick = nick->getText();
            channel->getText().empty() ? user.channel = "all" : user.channel = channel->getText();
            network->getText().empty() ? user.network = "all" : user.network = network->getText();
            m_preferences.m_ignoreUsersList.append(user);
            m_users->appendItem(user.nick+"\t"+user.channel+"\t"+user.network);
            if(!m_deleteUser->isEnabled()) m_deleteUser->enable();
            if(!m_modifyUser->isEnabled()) m_modifyUser->enable();
        }
    }
    return 1;
}

long ConfigDialog::onModifyUser(FXObject*, FXSelector, void*)
{
    FXint i = m_users->getCurrentItem();
    FXString oldnick = m_preferences.m_ignoreUsersList[i].nick;

    FXDialogBox dialog(this, _("Modify ignore user"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
    FXVerticalFrame *contents = new FXVerticalFrame(&dialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
    FXMatrix *matrix = new FXMatrix(contents,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);

    new FXLabel(matrix, _("Nick:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *nick = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    nick->setText(oldnick);
    new FXLabel(matrix, _("Channel(s):\tChannels need to be comma separated"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *channel = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    channel->setText(m_preferences.m_ignoreUsersList[i].channel);
    new FXLabel(matrix, _("Network:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *network = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    network->setText(m_preferences.m_ignoreUsersList[i].network);

    FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    new dxEXButton(buttonframe, _("&Cancel"), NULL, &dialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
    new dxEXButton(buttonframe, _("&OK"), NULL, &dialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);

    if(dialog.execute(PLACEMENT_CURSOR))
    {
        if(!nick->getText().empty() && (!nickExist(nick->getText()) || oldnick == nick->getText()))
        {
            m_preferences.m_ignoreUsersList[i].nick = nick->getText();
            channel->getText().empty() ? m_preferences.m_ignoreUsersList[i].channel = "all" : m_preferences.m_ignoreUsersList[i].channel = channel->getText();
            network->getText().empty() ? m_preferences.m_ignoreUsersList[i].network = "all" : m_preferences.m_ignoreUsersList[i].network = network->getText();
            m_users->setItemText(i, m_preferences.m_ignoreUsersList[i].nick+"\t"+m_preferences.m_ignoreUsersList[i].channel+"\t"+m_preferences.m_ignoreUsersList[i].network);
        }
    }
    return 1;
}

long ConfigDialog::onDeleteUser(FXObject*, FXSelector, void*)
{
    FXint i = m_users->getCurrentItem();
    m_users->removeItem(i);
    m_preferences.m_ignoreUsersList.erase(i);
    if(m_preferences.m_ignoreUsersList.no())
    {
        m_deleteUser->enable();
        m_modifyUser->enable();
    }
    else
    {
        m_deleteUser->disable();
        m_modifyUser->disable();
    }
    return 1;
}

long ConfigDialog::onImportSmiley(FXObject*, FXSelector, void*)
{
    if(m_showImportwarning && m_preferences.m_smileysMap.size())
        if(dxEXMessageBox::warning(this, MBOX_OK_CANCEL, _("Warning"), _("File import overwrites current settings"))==4) {m_showImportwarning=FALSE; return 1;}
    dxEXFileDialog dialog(this, _("Select file"));
    if(m_showImportwarning) dialog.setFilename((FXString)DXIRC_DATADIR+PATHSEPSTRING+"icons"+PATHSEPSTRING+"smileys"+PATHSEPSTRING+"dxirc.smiley");
    if(dialog.execute())
    {
        m_smileys->clearItems();
        m_preferences.m_smileysMap.clear();
        FXFile file(dialog.getFilename(), FXIO::Reading);
        if(file.isOpen())
        {
            FXchar line[MAXBUFFER];
            FXint bol,eol,end,path,smiley,p,lineno;
            FXString pathstr, smileystr;
            lineno=bol=eol=end=0;
            // Read lines
            while(readString(file,line,bol,eol,end))
            {
                lineno++;
                // Skip leading spaces
                while(bol<eol && Ascii::isBlank(line[bol])) bol++;
                // Skip comment lines and empty lines
                if(bol>=eol || line[bol]=='#' || line[bol]==';' || line[bol]=='\n' || line[bol]=='\r') goto next;
                // Scan key path
                for(path=bol; bol<eol && line[bol]!='=' && !Ascii::isControl(line[bol]); bol++);
                // Check errors
                if(bol>=eol || line[bol]!='='){ fxwarning("%s:%d: expected '=' to follow key.\n",dialog.getFilename().text(),lineno); goto next; }
                // Remove trailing spaces after path
                for(p=bol; path<p && Ascii::isBlank(line[p-1]); p--);
                // Terminate path
                line[p]='\0';
                // Skip leading spaces
                for(bol++; bol<eol && Ascii::isBlank(line[bol]); bol++);
                // Scan smiley
                for(smiley=bol; bol<eol && !Ascii::isControl(line[bol]); bol++);
                // Remove trailing spaces after smiley
                for(p=bol; smiley<p && Ascii::isBlank(line[p-1]); p--);
                // Terminate smiley
                line[p]='\0';
                //Fill smiley map
                pathstr = dequote(line+path);
                if(pathstr.empty()) goto next;
                smileystr = dequote(line+smiley);
                if(smileystr.empty()) goto next;
                pathstr = FXPath::absolute(FXPath::directory(dialog.getFilename()), pathstr);
                m_preferences.m_smileysMap.insert(StringPair(smileystr,pathstr));

next:           bol=eol;
            }
        }
        fillSmileys();
        if(m_preferences.m_smileysMap.size())
        {
            m_modifySmiley->enable();
            m_deleteSmiley->enable();
            m_exportSmiley->enable();
        }
    }
    m_showImportwarning=FALSE;
    return 1;
}

long ConfigDialog::onExportSmiley(FXObject*, FXSelector, void*)
{
    dxEXFileDialog dialog(this, _("Save smiley settings as"));
    if(dialog.execute())
    {
        FXFile file(dialog.getFilename(), FXIO::Writing);
        FXchar line[MAXVALUE];
        if(file.isOpen())
        {
            writeString(file, HEADER);
            if((FXint)m_preferences.m_smileysMap.size())
            {
                StringIt it;
                FXint i;
                for(i=0, it=m_preferences.m_smileysMap.begin(); it!=m_preferences.m_smileysMap.end(); it++,i++)
                {
                    writeString(file, enquote(line, FXPath::relative(FXPath::directory(dialog.getFilename()),(*it).second).text()));
                    writeString(file, "=");
                    writeString(file, enquote(line, (*it).first.text()));
                    writeString(file, ENDLINE);
                }
            }
        }
    }
    return 1;
}

long ConfigDialog::onLoadLog(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_loadLog) m_loadLineSpinner->enable();
    else m_loadLineSpinner->disable();
    return 1;
}

long ConfigDialog::onMouseWheel(FXObject *, FXSelector, void *ptr)
{
    FXEvent *event = (FXEvent*)ptr;
    FXint index = m_tabbook->getCurrent();
    if(event->code > 0) //positive movement
    {
        if(m_tabbook->numChildren())
        {
            if((index-1) >= 0) m_tabbook->setCurrent(index-1, TRUE);
            else m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
        }
    }
    else
    {
        if(m_tabbook->numChildren())
        {
            if((index+1)*2 < m_tabbook->numChildren()) m_tabbook->setCurrent(index+1, m_tabbook->numChildren() > index*2 ? TRUE : FALSE);
            else m_tabbook->setCurrent(0, TRUE);
        }
    }
    return 1;
}

long ConfigDialog::onModifyBindings(FXObject*, FXSelector, void*)
{
    KeybindingsDialog dialog(this);
    dialog.execute();
    return 1;
}

long ConfigDialog::onRefreshBindings(FXObject*, FXSelector, void*)
{
    dxEXMessageBox box(this, _("Restore default key bindings"), _("Do you really want to restore the default key bindings?\nAll your customizations will be lost!"), ICO_KEYBINDINGS, MBOX_OK_CANCEL|DECOR_TITLE|DECOR_BORDER);
    if(box.execute() != MBOX_CLICKED_OK)
        return 0;
    dxirc::instance()->setTempKeybindings(preferences.getDefaultKeybindings());
    if(dxEXMessageBox::question(this, MBOX_YES_NO, _("Restart"), _("Key bindings will be changed after restart.\nRestart dxirc now?"))==1)
    {
        dxirc::instance()->handle(this, FXSEL(SEL_COMMAND, dxirc_RESTART), NULL);
    }
    return 1;
}

// Enquote a value
FXchar* ConfigDialog::enquote(FXchar* result, const FXchar* text)
{
    register FXchar *end = result + MAXVALUE - 6;
    register FXchar *ptr = result;
    register FXuchar c;
    if (needquotes(text))
    {
        *ptr++ = '"';
        while((c = *text++) != '\0' && ptr < end)
        {
            switch (c) {
                case '\n':
                    *ptr++ = '\\';
                    *ptr++ = 'n';
                    break;
                case '\r':
                    *ptr++ = '\\';
                            *ptr++ = 'r';
                    break;
                case '\b':
                    *ptr++ = '\\';
                            *ptr++ = 'b';
                    break;
                case '\v':
                    *ptr++ = '\\';
                    *ptr++ = 'v';
                    break;
                case '\a':
                    *ptr++ = '\\';
                    *ptr++ = 'a';
                    break;
                case '\f':
                    *ptr++ = '\\';
                    *ptr++ = 'f';
                    break;
                case '\t':
                    *ptr++ = '\\';
                    *ptr++ = 't';
                    break;
                case '\\':
                    *ptr++ = '\\';
                    *ptr++ = '\\';
                    break;
                case '"':
                    *ptr++ = '\\';
                    *ptr++ = '"';
                    break;
                case '\'':
                    *ptr++ = '\\';
                    *ptr++ = '\'';
                    break;
                default:
                    if(c < 0x20 || 0x7f < c)
                    {
                        *ptr++ = '\\';
                        *ptr++ = 'x';
                        *ptr++ = FXString::HEX[c >> 4];
                        *ptr++ = FXString::HEX[c & 15];
                    }
                    else
                    {
                        *ptr++ = c;
                    }
                    break;
            }
        }
        *ptr++ = '"';
    }
    else
    {
        while ((c = *text++) != '\0' && ptr < end)
        {
            *ptr++ = c;
        }
    }
    *ptr = '\0';
    return result;
}

// Dequote a value, in situ
FXchar* ConfigDialog::dequote(FXchar* text) const
{
    register FXchar *result = text;
    register FXchar *ptr = text;
    register FXuint v;
    if(*text == '"')
    {
        text++;
        while((v = *text++) != '\0' && v != '\n' && v != '"')
        {
            if(v == '\\')
            {
                v = *text++;
                switch (v) {
                    case 'n':
                        v = '\n';
                        break;
                    case 'r':
                        v = '\r';
                        break;
                    case 'b':
                        v = '\b';
                        break;
                    case 'v':
                        v = '\v';
                        break;
                    case 'a':
                        v = '\a';
                        break;
                    case 'f':
                        v = '\f';
                        break;
                    case 't':
                        v = '\t';
                        break;
                    case '\\':
                        v = '\\';
                        break;
                    case '"':
                        v = '"';
                        break;
                    case '\'':
                        v = '\'';
                        break;
                    case 'x':
                        v = 'x';
                        if(Ascii::isHexDigit(*text))
                        {
                            v = Ascii::digitValue(*text++);
                            if(Ascii::isHexDigit(*text))
                            {
                                v = (v << 4) + Ascii::digitValue(*text++);
                            }
                        }
                        break;
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                        v = v - '0';
                        if('0' <= *text && *text <= '7')
                        {
                            v = (v << 3)+*text++-'0';
                            if('0' <= *text && *text <= '7')
                            {
                                v = (v << 3)+*text++-'0';
                            }
                        }
                        break;
                }
            }
            *ptr++ = v;
        }
        *ptr = '\0';
    }
    return result;
}

long ConfigDialog::onAddFriend(FXObject*, FXSelector, void*)
{
    FXDialogBox dialog(this, _("Add friend"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
    FXVerticalFrame *contents = new FXVerticalFrame(&dialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
    FXMatrix *matrix = new FXMatrix(contents,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);

    new FXLabel(matrix, _("Nick:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *nick = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    nick->setText("example");
    new FXLabel(matrix, _("Channel(s):\tChannels need to be comma separated"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *channel = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    channel->setText("#dxirc,#prd");
    channel->setTipText(_("Channels need to be comma separated"));
    new FXLabel(matrix, _("Network:"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *network = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    network->setText("freenode");

    FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    new dxEXButton(buttonframe, _("&Cancel"), NULL, &dialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
    new dxEXButton(buttonframe, _("&OK"), NULL, &dialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);

    if(dialog.execute(PLACEMENT_CURSOR))
    {
        if(!nick->getText().empty() && !nickExist(nick->getText(), FALSE))
        {
            UserInfo user;
            user.nick = nick->getText();
            channel->getText().empty() ? user.channel = "all" : user.channel = channel->getText();
            network->getText().empty() ? user.network = "all" : user.network = network->getText();
            m_preferences.m_friendsList.append(user);
            m_friends->appendItem(user.nick+"\t"+user.channel+"\t"+user.network);
            if(!m_deleteFriend->isEnabled()) m_deleteFriend->enable();
            if(!m_modifyFriend->isEnabled()) m_modifyFriend->enable();
        }
    }
    return 1;
}

long ConfigDialog::onModifyFriend(FXObject*, FXSelector, void*)
{
    FXint i = m_friends->getCurrentItem();
    FXString oldnick = m_preferences.m_friendsList[i].nick;

    FXDialogBox dialog(this, _("Modify friend"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
    FXVerticalFrame *contents = new FXVerticalFrame(&dialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
    FXMatrix *matrix = new FXMatrix(contents,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);

    new FXLabel(matrix, _("Nick:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *nick = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    nick->setText(oldnick);
    new FXLabel(matrix, _("Channel(s):\tChannels need to be comma separated"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *channel = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    channel->setText(m_preferences.m_friendsList[i].channel);
    new FXLabel(matrix, _("Network:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    FXTextField *network = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
    network->setText(m_preferences.m_friendsList[i].network);

    FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
    new dxEXButton(buttonframe, _("&Cancel"), NULL, &dialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
    new dxEXButton(buttonframe, _("&OK"), NULL, &dialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);

    if(dialog.execute(PLACEMENT_CURSOR))
    {
        if(!nick->getText().empty() && (!nickExist(nick->getText(), FALSE) || oldnick == nick->getText()))
        {
            m_preferences.m_friendsList[i].nick = nick->getText();
            channel->getText().empty() ? m_preferences.m_friendsList[i].channel = "all" : m_preferences.m_friendsList[i].channel = channel->getText();
            network->getText().empty() ? m_preferences.m_friendsList[i].network = "all" : m_preferences.m_friendsList[i].network = network->getText();
            m_friends->setItemText(i, m_preferences.m_friendsList[i].nick+"\t"+m_preferences.m_friendsList[i].channel+"\t"+m_preferences.m_friendsList[i].network);
        }
    }
    return 1;
}

long ConfigDialog::onDeleteFriend(FXObject*, FXSelector, void*)
{
    FXint i = m_friends->getCurrentItem();
    m_friends->removeItem(i);
    m_preferences.m_friendsList.erase(i);
    if(m_preferences.m_friendsList.no())
    {
        m_deleteFriend->enable();
        m_modifyFriend->enable();
    }
    else
    {
        m_deleteFriend->disable();
        m_modifyFriend->disable();
    }
    return 1;
}

long ConfigDialog::onAddIcons(FXObject*, FXSelector, void*)
{
    dxEXDirDialog dirdialog(this, _("Select theme directory"));
    if(dirdialog.execute(PLACEMENT_CURSOR))
    {
        if(!FXPath::search(dirdialog.getDirectory(), "irc_normal.png").empty() && !themeExist(dirdialog.getDirectory())) m_icons->appendItem(dirdialog.getDirectory());
    }
    m_icons->getNumItems()>1 ? m_deleteTheme->enable() : m_deleteTheme->disable();
    updateThemesList();
    updateNickIcons();
    return 1;
}

long ConfigDialog::onDeleteIcons(FXObject*, FXSelector, void*)
{
    FXint i = m_icons->getCurrentItem();
    m_icons->removeItem(i);
    i = m_icons->getCurrentItem();
    m_preferences.m_themePath = m_icons->getItemText(i);
    m_icons->getNumItems()>1 ? m_deleteTheme->enable() : m_deleteTheme->disable();
    updateThemesList();
    updateNickIcons();
    return 1;
}

long ConfigDialog::onIconsChanged(FXObject*, FXSelector, void *ptr)
{
    FXint i = (FXint)(FXival)ptr;
    m_preferences.m_themePath = m_icons->getItemText(i);
    updateNickIcons();
    return 1;
}

long ConfigDialog::onTheme(FXObject*, FXSelector, void *ptr)
{
    FXint no = (FXint)(FXival)ptr;
    ColorTheme *themeSelected = reinterpret_cast<ColorTheme*>(m_themes->getItemData(no));
    if(themeSelected)
    {
        m_themeCurrent.back = themeSelected->back;
        m_themeCurrent.base = themeSelected->base;
        m_themeCurrent.border = themeSelected->border;
        m_themeCurrent.fore = themeSelected->fore;
        m_themeCurrent.menuback = themeSelected->menuback;
        m_themeCurrent.menufore = themeSelected->menufore;
        m_themeCurrent.selback = themeSelected->selback;
        m_themeCurrent.selfore = themeSelected->selfore;
        m_themeCurrent.tipback = themeSelected->tipback;
        m_themeCurrent.tipfore = themeSelected->tipfore;
        m_themeCurrent.notifyback = themeSelected->notifyback;
        m_themeCurrent.notifyfore = themeSelected->notifyfore;
        if(m_themeCurrent.fore == m_preferences.m_unreadColor)
        {
            if(m_themeCurrent.fore != FXRGB(0,0,255)) m_preferences.m_unreadColor = FXRGB(0,0,255);
            else m_preferences.m_unreadColor = FXRGBA(FXREDVAL(m_themeCurrent.fore),FXGREENVAL(m_themeCurrent.fore),FXBLUEVAL(m_themeCurrent.fore)+1,FXALPHAVAL(m_themeCurrent.fore));
        }
        if(m_themeCurrent.fore == m_preferences.m_highlightColor)
        {
            if(m_themeCurrent.fore != FXRGB(255,0,0)) m_preferences.m_highlightColor = FXRGB(255,0,0);
            else m_preferences.m_highlightColor = FXRGBA(FXREDVAL(m_themeCurrent.fore)+1,FXGREENVAL(m_themeCurrent.fore),FXBLUEVAL(m_themeCurrent.fore),FXALPHAVAL(m_themeCurrent.fore));
        }
        updateColors();
    }
    return 1;
}

long ConfigDialog::onFont(FXObject*, FXSelector, void*)
{
    dxEXFontDialog dialog(this, _("Select font"));
    FXFontDesc fontdescription;
    m_font->getFontDesc(fontdescription);
    strncpy(fontdescription.face,m_font->getActualName().text(),sizeof(fontdescription.face));
    dialog.setFontSelection(fontdescription);
    if(dialog.execute(PLACEMENT_SCREEN))
    {
        FXFont *oldfont = m_font;
        dialog.getFontSelection(fontdescription);
        m_font = new FXFont(getApp(),fontdescription);
        m_font->create();
        delete oldfont;
        updateFont();
    }
    return 1;
}

long ConfigDialog::onIrcFont(FXObject*, FXSelector, void*)
{
    dxEXFontDialog dialog(this, _("Select font"));
    FXFontDesc fontdescription;
    m_ircFont->getFontDesc(fontdescription);
    strncpy(fontdescription.face,m_ircFont->getActualName().text(),sizeof(fontdescription.face));
    dialog.setFontSelection(fontdescription);
    if(dialog.execute(PLACEMENT_SCREEN))
    {
        FXFont *oldfont = m_ircFont;
        dialog.getFontSelection(fontdescription);
        m_ircFont = new FXFont(getApp(),fontdescription);
        m_ircFont->create();
        delete oldfont;
        updateIrcFont();
    }
    return 1;
}

long ConfigDialog::onThemeColorChanged(FXObject*obj, FXSelector, void*)
{
    m_themes->setCurrentItem(m_themes->getNumItems()-1);
    updateColors();
    return 1;
}

void ConfigDialog::updateColors()
{
    m_themeCurrent.shadow = makeShadowColor(m_themeCurrent.base);
    m_themeCurrent.hilite = makeHiliteColor(m_themeCurrent.base);

    m_vframe2->setBorderColor(m_themeCurrent.border);
    m_vframe2->setBaseColor(m_themeCurrent.base);
    m_vframe2->setBackColor(m_themeCurrent.base);
    m_vframe2->setShadowColor(m_themeCurrent.shadow);
    m_vframe2->setHiliteColor(m_themeCurrent.hilite);

    m_label->setBorderColor(m_themeCurrent.border);
    m_label->setBaseColor(m_themeCurrent.base);
    m_label->setBackColor(m_themeCurrent.base);
    m_label->setTextColor(m_themeCurrent.fore);
    m_label->setShadowColor(m_themeCurrent.shadow);
    m_label->setHiliteColor(m_themeCurrent.hilite);

    m_textFrame1->setBorderColor(m_themeCurrent.border);
    m_textFrame1->setBaseColor(m_themeCurrent.base);
    m_textFrame1->setBackColor(m_themeCurrent.base);
    m_textFrame1->setShadowColor(m_themeCurrent.shadow);
    m_textFrame1->setHiliteColor(m_themeCurrent.hilite);
    m_textTest->setBorderColor(m_themeCurrent.border);
    m_textTest->setBackColor(m_themeCurrent.back);
    m_textTest->setBaseColor(m_themeCurrent.base);
    m_textTest->setTextColor(m_themeCurrent.fore);
    m_textTest->setSelTextColor(m_themeCurrent.selfore);
    m_textTest->setSelBackColor(m_themeCurrent.selback);
    m_textTest->setCursorColor(m_themeCurrent.fore);
    m_textTest->setShadowColor(m_themeCurrent.shadow);
    m_textTest->setHiliteColor(m_themeCurrent.hilite);

    m_textFrame2->setBorderColor(m_themeCurrent.border);
    m_textFrame2->setBaseColor(m_themeCurrent.base);
    m_textFrame2->setBackColor(m_themeCurrent.back);
    m_textFrame2->setShadowColor(m_themeCurrent.shadow);
    m_textFrame2->setHiliteColor(m_themeCurrent.hilite);
    m_labelSelected->setBorderColor(m_themeCurrent.border);
    m_labelSelected->setBaseColor(m_themeCurrent.base);
    m_labelSelected->setBackColor(m_themeCurrent.selback);
    m_labelSelected->setTextColor(m_themeCurrent.selfore);
    m_labelSelected->setShadowColor(m_themeCurrent.shadow);
    m_labelSelected->setHiliteColor(m_themeCurrent.hilite);

    m_textFrame3->setBorderColor(m_themeCurrent.border);
    m_textFrame3->setBaseColor(m_themeCurrent.base);
    m_textFrame3->setBackColor(m_themeCurrent.back);
    m_textFrame3->setShadowColor(m_themeCurrent.shadow);
    m_textFrame3->setHiliteColor(m_themeCurrent.hilite);
    m_labelNocurrent->setBorderColor(m_themeCurrent.border);
    m_labelNocurrent->setBaseColor(m_themeCurrent.base);
    m_labelNocurrent->setBackColor(m_themeCurrent.base);
    m_labelNocurrent->setTextColor(m_themeCurrent.fore);
    m_labelNocurrent->setShadowColor(m_themeCurrent.shadow);
    m_labelNocurrent->setHiliteColor(m_themeCurrent.hilite);

    m_sep1->setBorderColor(m_themeCurrent.border);
    m_sep1->setBaseColor(m_themeCurrent.base);
    m_sep1->setBackColor(m_themeCurrent.base);
    m_sep1->setShadowColor(m_themeCurrent.shadow);
    m_sep1->setHiliteColor(m_themeCurrent.hilite);

    m_labelTip->setBorderColor(m_themeCurrent.tipfore);
    m_labelTip->setBaseColor(m_themeCurrent.tipback);
    m_labelTip->setBackColor(m_themeCurrent.tipback);
    m_labelTip->setTextColor(m_themeCurrent.tipfore);
    m_labelTip->setShadowColor(m_themeCurrent.shadow);
    m_labelTip->setHiliteColor(m_themeCurrent.hilite);

#ifndef HAVE_LIBNOTIFY
    m_labelNotify->setBorderColor(m_themeCurrent.notifyfore);
    m_labelNotify->setBaseColor(m_themeCurrent.notifyback);
    m_labelNotify->setBackColor(m_themeCurrent.notifyback);
    m_labelNotify->setTextColor(m_themeCurrent.notifyfore);
    m_labelNotify->setShadowColor(m_themeCurrent.shadow);
    m_labelNotify->setHiliteColor(m_themeCurrent.hilite);
#endif

    m_menuGroup->setBorderColor(m_themeCurrent.border);
    m_menuGroup->setBaseColor(m_themeCurrent.base);
    m_menuGroup->setBackColor(m_themeCurrent.base);
    m_menuGroup->setShadowColor(m_themeCurrent.shadow);
    m_menuGroup->setHiliteColor(m_themeCurrent.hilite);
    m_menuGroup->setTextColor(m_themeCurrent.fore);
    m_menuFrame->setBorderColor(m_themeCurrent.border);
    m_menuFrame->setBaseColor(m_themeCurrent.base);
    m_menuFrame->setBackColor(m_themeCurrent.base);
    m_menuFrame->setShadowColor(m_themeCurrent.shadow);
    m_menuFrame->setHiliteColor(m_themeCurrent.hilite);
    m_sep2->setBorderColor(m_themeCurrent.border);
    m_sep2->setBaseColor(m_themeCurrent.base);
    m_sep2->setBackColor(m_themeCurrent.base);
    m_sep2->setShadowColor(m_themeCurrent.shadow);
    m_sep2->setHiliteColor(m_themeCurrent.hilite);
    for(int i=0; i<3; i++)
    {
        m_menuLabels[i]->setBorderColor(m_themeCurrent.border);
        m_menuLabels[i]->setBaseColor(m_themeCurrent.base);
        m_menuLabels[i]->setBackColor(m_themeCurrent.base);
        m_menuLabels[i]->setTextColor(m_themeCurrent.fore);
        m_menuLabels[i]->setShadowColor(m_themeCurrent.shadow);
        m_menuLabels[i]->setHiliteColor(m_themeCurrent.hilite);
    }
    m_menuLabels[1]->setBorderColor(m_themeCurrent.border);
    m_menuLabels[1]->setBaseColor(m_themeCurrent.menuback);
    m_menuLabels[1]->setBackColor(m_themeCurrent.menuback);
    m_menuLabels[1]->setTextColor(m_themeCurrent.menufore);
    m_menuLabels[1]->setShadowColor(m_themeCurrent.shadow);
    m_menuLabels[1]->setHiliteColor(m_themeCurrent.hilite);

    m_tabFrame->setBorderColor(m_themeCurrent.border);
    m_tabFrame->setBaseColor(m_themeCurrent.base);
    m_tabFrame->setBackColor(m_themeCurrent.base);
    m_tabFrame->setShadowColor(m_themeCurrent.shadow);
    m_tabFrame->setHiliteColor(m_themeCurrent.hilite);
    m_tabs->setBorderColor(m_themeCurrent.border);
    m_tabs->setBaseColor(m_themeCurrent.base);
    m_tabs->setBackColor(m_themeCurrent.base);
    m_tabs->setShadowColor(m_themeCurrent.shadow);
    m_tabs->setHiliteColor(m_themeCurrent.hilite);
    m_tabframe1->setBorderColor(m_themeCurrent.border);
    m_tabframe1->setBaseColor(m_themeCurrent.base);
    m_tabframe1->setBackColor(m_themeCurrent.base);
    m_tabframe1->setShadowColor(m_themeCurrent.shadow);
    m_tabframe1->setHiliteColor(m_themeCurrent.hilite);
    m_tabframe2->setBorderColor(m_themeCurrent.border);
    m_tabframe2->setBaseColor(m_themeCurrent.base);
    m_tabframe2->setBackColor(m_themeCurrent.base);
    m_tabframe2->setShadowColor(m_themeCurrent.shadow);
    m_tabframe2->setHiliteColor(m_themeCurrent.hilite);
    m_tabframe3->setBorderColor(m_themeCurrent.border);
    m_tabframe3->setBaseColor(m_themeCurrent.base);
    m_tabframe3->setBackColor(m_themeCurrent.base);
    m_tabframe3->setShadowColor(m_themeCurrent.shadow);
    m_tabframe3->setHiliteColor(m_themeCurrent.hilite);
    m_tab->setBorderColor(m_themeCurrent.border);
    m_tab->setBaseColor(m_themeCurrent.base);
    m_tab->setBackColor(m_themeCurrent.base);
    m_tab->setTextColor(m_themeCurrent.fore);
    m_tab->setShadowColor(m_themeCurrent.shadow);
    m_tab->setHiliteColor(m_themeCurrent.hilite);
    m_unread->setBorderColor(m_themeCurrent.border);
    m_unread->setBaseColor(m_themeCurrent.base);
    m_unread->setBackColor(m_themeCurrent.base);
    m_unread->setTextColor(m_preferences.m_unreadColor);
    m_unread->setShadowColor(m_themeCurrent.shadow);
    m_unread->setHiliteColor(m_themeCurrent.hilite);
    m_highlight->setBorderColor(m_themeCurrent.border);
    m_highlight->setBaseColor(m_themeCurrent.base);
    m_highlight->setBackColor(m_themeCurrent.base);
    m_highlight->setTextColor(m_preferences.m_highlightColor);
    m_highlight->setShadowColor(m_themeCurrent.shadow);
    m_highlight->setHiliteColor(m_themeCurrent.hilite);
    m_tabLabel1->setBorderColor(m_themeCurrent.border);
    m_tabLabel1->setBaseColor(m_themeCurrent.base);
    m_tabLabel1->setBackColor(m_themeCurrent.base);
    m_tabLabel1->setTextColor(m_themeCurrent.fore);
    m_tabLabel1->setShadowColor(m_themeCurrent.shadow);
    m_tabLabel1->setHiliteColor(m_themeCurrent.hilite);
    m_tabLabel2->setBorderColor(m_themeCurrent.border);
    m_tabLabel2->setBaseColor(m_themeCurrent.base);
    m_tabLabel2->setBackColor(m_themeCurrent.base);
    m_tabLabel2->setTextColor(m_themeCurrent.fore);
    m_tabLabel2->setShadowColor(m_themeCurrent.shadow);
    m_tabLabel2->setHiliteColor(m_themeCurrent.hilite);
    m_tabLabel3->setBorderColor(m_themeCurrent.border);
    m_tabLabel3->setBaseColor(m_themeCurrent.base);
    m_tabLabel3->setBackColor(m_themeCurrent.base);
    m_tabLabel3->setTextColor(m_themeCurrent.fore);
    m_tabLabel3->setShadowColor(m_themeCurrent.shadow);
    m_tabLabel3->setHiliteColor(m_themeCurrent.hilite);
}

long ConfigDialog::onTabColorChanged(FXObject*obj, FXSelector, void*)
{
    if(m_themeCurrent.fore == m_preferences.m_unreadColor)
    {
        if(m_themeCurrent.fore != FXRGB(0,0,255)) m_preferences.m_unreadColor = FXRGB(0,0,255);
        else m_preferences.m_unreadColor = FXRGBA(FXREDVAL(m_themeCurrent.fore),FXGREENVAL(m_themeCurrent.fore),FXBLUEVAL(m_themeCurrent.fore)+1,FXALPHAVAL(m_themeCurrent.fore));
    }
    if(m_themeCurrent.fore == m_preferences.m_highlightColor)
    {
        if(m_themeCurrent.fore != FXRGB(255,0,0)) m_preferences.m_highlightColor = FXRGB(255,0,0);
        else m_preferences.m_highlightColor = FXRGBA(FXREDVAL(m_themeCurrent.fore)+1,FXGREENVAL(m_themeCurrent.fore),FXBLUEVAL(m_themeCurrent.fore),FXALPHAVAL(m_themeCurrent.fore));
    }
    m_unread->setTextColor(m_preferences.m_unreadColor);
    m_highlight->setTextColor(m_preferences.m_highlightColor);
    return 1;
}

static FXString weightToString(FXuint weight){
    switch(weight)
    {
        case FXFont::Thin      : return "thin";
        case FXFont::ExtraLight: return "extralight";
        case FXFont::Light     : return "light";
        case FXFont::Normal    : return "normal";
        case FXFont::Medium    : return "medium";
        case FXFont::DemiBold  : return "demibold";
        case FXFont::Bold      : return "bold";
        case FXFont::ExtraBold : return "extrabold";
        case FXFont::Black     : return "heavy";
        default: return ""; break;
    }
    return "";
}

static FXString slantToString(FXuint slant)
{
    switch(slant)
    {
        case FXFont::Straight       : return "regular";
        case FXFont::Italic         : return "italic";
        case FXFont::Oblique        : return "oblique";
        case FXFont::ReverseItalic  : return "reverse italic";
        case FXFont::ReverseOblique : return "reverse oblique";
        default : return "";
    }
    return "";
}

void ConfigDialog::updateFont()
{
    FXString fontname = m_font->getActualName() +", " + FXStringVal(m_font->getSize()/10);
    if(m_font->getWeight()!=0 && m_font->getWeight()!=FXFont::Normal)
    {
        fontname += ", " + weightToString(m_font->getWeight());
    }
    if (m_font->getSlant()!=0 && m_font->getSlant()!=FXFont::Straight)
    {
        fontname += ", " + slantToString(m_font->getSlant());
    }
    m_fontButton->setText(fontname);

    m_labelSelected->setFont(m_font);
    m_labelNocurrent->setFont(m_font);
    m_labelTip->setFont(m_font);
    m_label->setFont(m_font);
    m_textTest->setFont(m_font);
    m_menuGroup->setFont(m_font);
    m_menuLabels[0]->setFont(m_font);
    m_menuLabels[1]->setFont(m_font);
    m_menuLabels[2]->setFont(m_font);
    m_tab->setFont(m_font);
    m_unread->setFont(m_font);
    m_highlight->setFont(m_font);
}

void ConfigDialog::updateIrcFont()
{
    FXString fontname = m_ircFont->getActualName() +", " + FXStringVal(m_ircFont->getSize()/10);
    if(m_ircFont->getWeight()!=0 && m_ircFont->getWeight()!=FXFont::Normal)
    {
        fontname += ", " + weightToString(m_ircFont->getWeight());
    }
    if (m_ircFont->getSlant()!=0 && m_ircFont->getSlant()!=FXFont::Straight)
    {
        fontname += ", " + slantToString(m_ircFont->getSlant());
    }
    m_ircfontButton->setText(fontname);

    m_text->setFont(m_ircFont);
}

long ConfigDialog::onLogChanged(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_logging)
    {
        m_selectPath->enable();
        m_loadLogButton->enable();
    }
    else
    {
        m_selectPath->disable();
        m_preferences.m_loadLog = false;
        m_loadLogButton->disable();
        m_loadLineSpinner->disable();
    }
    return 1;
}

long ConfigDialog::onAutoloadChanged(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_autoload) m_selectAutoloadPath->enable();
    else m_selectAutoloadPath->disable();
    return 1;
}

long ConfigDialog::onNickCharChanged(FXObject*, FXSelector, void*)
{
    m_preferences.m_nickCompletionChar = m_nickCharField->getText().left(1);
    m_nickCharField->setText(m_preferences.m_nickCompletionChar);
    return 1;
}

long ConfigDialog::onTray(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_useTray)
        m_closeToTrayButton->enable();
    else
    {
        m_preferences.m_closeToTray = FALSE;
        m_closeToTrayButton->disable();
    }
    return 1;
}

long ConfigDialog::onReconnect(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_reconnect)
    {
        m_numberAttemptLabel->enable();
        m_numberAttemptSpinner->enable();
        m_delayAttemptLabel->enable();
        m_delayAttemptSpinner->enable();
    }
    else
    {
        m_numberAttemptLabel->disable();
        m_numberAttemptSpinner->disable();
        m_delayAttemptLabel->disable();
        m_delayAttemptSpinner->disable();
    }
    return 1;
}

long ConfigDialog::onPathSelect(FXObject*, FXSelector, void*)
{
    dxEXDirDialog dirdialog(this,_("Select log directory"));
    dirdialog.setDirectory(m_preferences.m_logPath);
    if(dirdialog.execute(PLACEMENT_CURSOR))
    {
        m_preferences.m_logPath = dirdialog.getDirectory();
    }
    return 1;
}

long ConfigDialog::onAutoloadPathSelect(FXObject*, FXSelector, void*)
{
    dxEXDirDialog dirdialog(this,_("Select autoload directory"));
    dirdialog.setDirectory(m_preferences.m_autoloadPath);
    if(dirdialog.execute(PLACEMENT_CURSOR))
    {
        m_preferences.m_autoloadPath = dirdialog.getDirectory();
    }
    return 1;
}

long ConfigDialog::onDccPathSelect(FXObject*, FXSelector, void*)
{
    dxEXDirDialog dirdialog(this,_("Select directory"));
    dirdialog.setDirectory(m_preferences.m_dccPath);
    if(dirdialog.execute(PLACEMENT_CURSOR))
    {
        m_preferences.m_dccPath = dirdialog.getDirectory();
    }
    return 1;
}

long ConfigDialog::onDccPortD(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_dccPortD<0 || m_preferences.m_dccPortD>65536) m_preferences.m_dccPortD = 0;
    if(m_preferences.m_dccPortH<m_preferences.m_dccPortD) m_preferences.m_dccPortH = m_preferences.m_dccPortD;
    return 1;
}

long ConfigDialog::onDccPortH(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_dccPortH<0 || m_preferences.m_dccPortH>65536) m_preferences.m_dccPortH = 0;
    if(m_preferences.m_dccPortD>m_preferences.m_dccPortH) m_preferences.m_dccPortD = m_preferences.m_dccPortH;
    return 1;
}

long ConfigDialog::onSounds(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_sounds)
    {
        m_checkConnect->enable();
        m_selectConnect->enable();
        if(FXStat::exists(m_preferences.m_pathConnect)) m_playConnect->enable();
        m_checkDisconnect->enable();
        m_selectDisconnect->enable();
        if(FXStat::exists(m_preferences.m_pathDisconnect)) m_playDisconnect->enable();
        m_checkMessage->enable();
        m_selectMessage->enable();
        if(FXStat::exists(m_preferences.m_pathMessage)) m_playMessage->enable();
    }
    else
    {
        m_checkConnect->disable();
        m_selectConnect->disable();
        m_playConnect->disable();
        m_checkDisconnect->disable();
        m_selectDisconnect->disable();
        m_playDisconnect->disable();
        m_checkMessage->disable();
        m_selectMessage->disable();
        m_playMessage->disable();
        m_addFriend->disable();
        m_modifyFriend->disable();
        m_deleteFriend->disable();
    }
    if(m_preferences.m_sounds || m_preferences.m_notify)
    {
        m_addFriend->enable();
        if(m_preferences.m_friendsList.no())
        {
            m_deleteFriend->enable();
            m_modifyFriend->enable();
        }
    }
    else
    {
        m_addFriend->disable();
        m_modifyFriend->disable();
        m_deleteFriend->disable();
    }
    return 1;
}

long ConfigDialog::onSoundConnect(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_soundConnect)
    {
        m_selectConnect->enable();
        if(FXStat::exists(m_preferences.m_pathConnect)) m_playConnect->enable();
    }
    else
    {
        m_selectConnect->disable();
        m_playConnect->enable();
    }
    return 1;
}

long ConfigDialog::onSoundDisconnect(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_soundDisconnect)
    {
        m_selectDisconnect->enable();
        if(FXStat::exists(m_preferences.m_pathDisconnect)) m_playDisconnect->enable();
    }
    else
    {
        m_selectDisconnect->disable();
        m_playDisconnect->enable();
    }
    return 1;
}

long ConfigDialog::onSoundMessage(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_soundMessage)
    {
        m_selectMessage->enable();
        if(FXStat::exists(m_preferences.m_pathMessage)) m_playMessage->enable();
    }
    else
    {
        m_selectMessage->disable();
        m_playMessage->enable();
    }
    return 1;
}

long ConfigDialog::onPlay(FXObject*, FXSelector sel, void*)
{
    switch(FXSELID(sel)) {
        case ConfigDialog_PLAYCONNECT:
            utils::playFile(m_preferences.m_pathConnect);
            return 1;
        case ConfigDialog_PLAYDISCONNECT:
            utils::playFile(m_preferences.m_pathDisconnect);
            return 1;
        case ConfigDialog_PLAYMESSAGE:
            utils::playFile(m_preferences.m_pathMessage);
            return 1;
    }
    return 1;
}

long ConfigDialog::onSelectPath(FXObject*, FXSelector sel, void*)
{
    dxEXFileDialog file(this, _("Select file"));
    file.setPatternList(_("Sound file (*.wav)"));
    switch(FXSELID(sel)) {
        case ConfigDialog_SELECTCONNECT:
            if(file.execute(PLACEMENT_CURSOR))
            {
                m_preferences.m_pathConnect = file.getFilename();
                m_playConnect->enable();
            }
            return 1;
        case ConfigDialog_SELECTDISCONNECT:
            if(file.execute(PLACEMENT_CURSOR))
            {
                m_preferences.m_pathDisconnect = file.getFilename();
                m_playDisconnect->enable();
            }
            return 1;
        case ConfigDialog_SELECTMESSAGE:
            if(file.execute(PLACEMENT_CURSOR))
            {
                m_preferences.m_pathMessage = file.getFilename();
                m_playMessage->enable();
            }
            return 1;
    }
    return 1;
}

long ConfigDialog::onNotify(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_notify)
    {
        m_checkNotifyConnect->enable();
        m_checkNotifyDisconnect->enable();
        m_checkNotifyMessage->enable();
    }
    else
    {
        m_checkNotifyConnect->disable();
        m_checkNotifyDisconnect->disable();
        m_checkNotifyMessage->disable();
    }
    if(m_preferences.m_sounds || m_preferences.m_notify)
    {
        m_addFriend->enable();
        if(m_preferences.m_friendsList.no())
        {
            m_deleteFriend->enable();
            m_modifyFriend->enable();
        }
    }
    else
    {
        m_addFriend->disable();
        m_modifyFriend->disable();
        m_deleteFriend->disable();
    }
    return 1;
}

long ConfigDialog::onShowNotify(FXObject*, FXSelector, void*)
{
    dxirc::instance()->showNotify(FXStringFormat(_("%s has joined to %s"), "dvx", "#dxirc"), m_preferences.m_notifyPosition);
    return 1;
}

long ConfigDialog::onUseSmileys(FXObject*, FXSelector, void*)
{
    if(m_preferences.m_useSmileys)
    {
        m_addSmiley->enable();
        m_importSmiley->enable();
        if((FXint)m_preferences.m_smileysMap.size())
        {
            m_modifySmiley->enable();
            m_deleteSmiley->enable();
            m_exportSmiley->enable();
        }
        else
        {
            m_modifySmiley->disable();
            m_deleteSmiley->disable();
            m_exportSmiley->disable();
        }
    }
    else
    {
        m_addSmiley->disable();
        m_modifySmiley->disable();
        m_deleteSmiley->disable();
        m_importSmiley->disable();
        m_exportSmiley->disable();
    }
    return 1;
}

long ConfigDialog::onAddSmiley(FXObject*, FXSelector, void*)
{
    if((FXint)m_preferences.m_smileysMap.size()>=256)
    {
        dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("Maximum number of 256 smileys is reached"));
        return 1;
    }
    SmileyDialog dialog(this, _("Add smiley"), "", "");
    if(dialog.execute())
    {
        if(!dialog.iconExist())
        {
            dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("Icon file '%s' doesn't exist or isn't image file"), dialog.getPath().text());
            return 1;
        }
        if(dialog.getSmiley().empty())
        {
            dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("Smiley text is empty"));
            return 1;
        }
        if(smileyExist(dialog.getSmiley()))
        {
            dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("Smiley '%s' already exist"), dialog.getSmiley().text());
            return 1;
        }
        m_preferences.m_smileysMap.insert(StringPair(dialog.getSmiley(), dialog.getPath()));
        m_smileys->appendItem(new FXListItem(dialog.getSmiley(), dialog.getIcon()));
        m_modifySmiley->enable();
        m_deleteSmiley->enable();
        m_exportSmiley->enable();
    }
    return 1;
}

long ConfigDialog::onModifySmiley(FXObject*, FXSelector, void*)
{
    FXint index = m_smileys->getCurrentItem();
    FXString oldkey = m_smileys->getItemText(index);
    SmileyDialog dialog(this, _("Modify smiley"), oldkey, m_preferences.m_smileysMap[oldkey]);
    if(dialog.execute())
    {
        if(!dialog.iconExist())
        {
            dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("Icon file '%s' doesn't exist or isn't image file"), dialog.getPath().text());
            return 1;
        }
        if(dialog.getSmiley().empty())
        {
            dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("Smiley text is empty"));
            return 1;
        }
        if(smileyExist(dialog.getSmiley()) && dialog.getSmiley()!=oldkey)
        {
            dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("Smiley '%s' already exist"), dialog.getSmiley().text());
            return 1;
        }
        m_preferences.m_smileysMap.erase(oldkey);
        m_smileys->removeItem(index, TRUE);
        m_preferences.m_smileysMap.insert(StringPair(dialog.getSmiley(), dialog.getPath()));
        m_smileys->insertItem(index, new FXListItem(dialog.getSmiley(), dialog.getIcon()), TRUE);
        m_smileys->setCurrentItem(index, TRUE);
    }
    return 1;
}

long ConfigDialog::onDeleteSmiley(FXObject*, FXSelector, void*)
{
    m_preferences.m_smileysMap.erase(m_smileys->getItemText(m_smileys->getCurrentItem()));
    m_smileys->removeItem(m_smileys->getCurrentItem(), TRUE);
    if(!(FXint)m_preferences.m_smileysMap.size())
    {
        m_modifySmiley->disable();
        m_deleteSmiley->disable();
        m_exportSmiley->disable();
    }
    return 1;
}

void ConfigDialog::fillCommnads()
{
    if(!m_preferences.m_ignoreCommandsList.empty())
    {
        for(FXint i=0; i<m_preferences.m_ignoreCommandsList.contains(';'); i++)
        {
            m_commands->appendItem(m_preferences.m_ignoreCommandsList.before(';', i+1).rafter(';'));
        }
    }
}

void ConfigDialog::fillIcons()
{
    if(!m_preferences.m_themesList.empty())
    {
        for(FXint i=0; i<m_preferences.m_themesList.contains(';'); i++)
        {
            m_icons->appendItem(m_preferences.m_themesList.before(';', i+1).rafter(';'));
        }
    }
}

void ConfigDialog::fillThemes()
{
    FXint i, scheme=-1;

    for(i=0; i<numThemes; i++)
    {
        if((m_themeCurrent.back == ColorThemes[i].back) &&
                (m_themeCurrent.base == ColorThemes[i].base) &&
                (m_themeCurrent.border == ColorThemes[i].border) &&
                (m_themeCurrent.fore == ColorThemes[i].fore) &&
                (m_themeCurrent.menuback == ColorThemes[i].menuback) &&
                (m_themeCurrent.menufore == ColorThemes[i].menufore) &&
                (m_themeCurrent.selback == ColorThemes[i].selback) &&
                (m_themeCurrent.selfore == ColorThemes[i].selfore) &&
                (m_themeCurrent.tipback == ColorThemes[i].tipback) &&
                (m_themeCurrent.tipfore == ColorThemes[i].tipfore) &&
                (m_themeCurrent.notifyback == ColorThemes[i].notifyback) &&
                (m_themeCurrent.notifyfore == ColorThemes[i].notifyfore))
        {
            scheme = i;
        }
        m_themes->appendItem(ColorThemes[i].name,NULL,(void*)&ColorThemes[i]);
    }

    if(scheme == -1)
        scheme = numThemes;

    m_themes->appendItem(_("User Defined"), NULL, &m_themeCurrent);
    m_themes->setCurrentItem(scheme);
}

FXString ConfigDialog::fillCommandsCombo()
{
    FXString combo;
    FXString available[11] = { "away", "ban", "ctcp", "invite", "join", "me", "nick", "notice", "mode", "part", "quit"};
    for(FXint i=0; i<11; i++)
    {
        FXbool exist = FALSE;
        for(FXint j=0; j<m_commands->getNumItems(); j++)
        {
            if(m_commands->getItemText(j) == available[i])
            {
                exist = TRUE;
                break;
            }
        }
        if(!exist) combo.append(available[i]+'\n');
    }
    return combo;
}

void ConfigDialog::fillUsers()
{
    if(m_preferences.m_ignoreUsersList.no())
    {
        for(FXint i=0; i<m_preferences.m_ignoreUsersList.no(); i++)
        {
            m_users->appendItem(m_preferences.m_ignoreUsersList[i].nick+"\t"+m_preferences.m_ignoreUsersList[i].channel+"\t"+m_preferences.m_ignoreUsersList[i].network);
        }
    }
}

void ConfigDialog::fillFriends()
{
    if(m_preferences.m_friendsList.no())
    {
        for(FXint i=0; i<m_preferences.m_friendsList.no(); i++)
        {
            m_friends->appendItem(m_preferences.m_friendsList[i].nick+"\t"+m_preferences.m_friendsList[i].channel+"\t"+m_preferences.m_friendsList[i].network);
        }
    }
}

void ConfigDialog::fillSmileys()
{
    if((FXint)m_preferences.m_smileysMap.size())
    {
        StringIt it;
        for(it=m_preferences.m_smileysMap.begin(); it!=m_preferences.m_smileysMap.end(); it++)
        {
            m_smileys->appendItem(new FXListItem((*it).first, createIconFromName(getApp(), (*it).second)));
        }
    }
}

void ConfigDialog::updateCommands()
{
    m_preferences.m_ignoreCommandsList.clear();
    for(FXint i=0; i<m_commands->getNumItems(); i++)
    {
        m_preferences.m_ignoreCommandsList.append(m_commands->getItemText(i)+';');
    }
    if(m_commands->getNumItems()) m_deleteCommand->enable();
}

void ConfigDialog::updateThemesList()
{
    m_preferences.m_themesList.clear();
    for(FXint i=0; i<m_icons->getNumItems(); i++)
    {
        m_preferences.m_themesList.append(m_icons->getItemText(i)+';');
    }
}

void ConfigDialog::updateNickIcons()
{
    if(m_preferences.m_themePath=="internal")
    {
        m_icon1->setText("!");
        m_icon2->setText("*");
        m_icon3->setText("@");
        m_icon4->setText("%");
        m_icon5->setText("+");
        m_icon6->setText(" ");
        m_icon7->setText(" ");
        m_icon1->setIcon(NULL);
        m_icon2->setIcon(NULL);
        m_icon3->setIcon(NULL);
        m_icon4->setIcon(NULL);
        m_icon5->setIcon(NULL);
        m_icon6->setIcon(NULL);
        m_icon7->setIcon(NULL);
    }
    else
    {
        m_icon1->setText("");
        m_icon2->setText("");
        m_icon3->setText("");
        m_icon4->setText("");
        m_icon5->setText("");
        m_icon6->setText("");
        m_icon7->setText("");
        m_icon1->setIcon(makeIcon(getApp(), m_preferences.m_themePath, "irc_admin.png", TRUE));
        m_icon2->setIcon(makeIcon(getApp(), m_preferences.m_themePath, "irc_owner.png", TRUE));
        m_icon3->setIcon(makeIcon(getApp(), m_preferences.m_themePath, "irc_op.png", TRUE));
        m_icon4->setIcon(makeIcon(getApp(), m_preferences.m_themePath, "irc_halfop.png", TRUE));
        m_icon5->setIcon(makeIcon(getApp(), m_preferences.m_themePath, "irc_voice.png", TRUE));
        m_icon6->setIcon(makeIcon(getApp(), m_preferences.m_themePath, "irc_normal.png", TRUE));
        m_icon7->setIcon(makeAwayIcon(getApp(), m_preferences.m_themePath, "irc_normal.png"));
    }
}

FXbool ConfigDialog::themeExist(const FXString &ckdTheme)
{
    for(FXint i=0; i<m_icons->getNumItems(); i++)
    {
        if(m_icons->getItemText(i) == ckdTheme)
        {
            return TRUE;
        }
    }
    return FALSE;
}

FXbool ConfigDialog::nickExist(const FXString &ckdNick, FXbool user)
{
    for(FXint i=0; i<(user ? m_users->getNumItems() : m_friends->getNumItems()); i++)
    {
        if((user ? m_users->getItemText(i) : m_friends->getItemText(i)) == ckdNick) return TRUE;
    }
    return FALSE;
}

FXbool ConfigDialog::smileyExist(const FXString& ckdSmiley)
{
    StringIt it;
    for(it=m_preferences.m_smileysMap.begin(); it!=m_preferences.m_smileysMap.end(); it++)
    {
        if(!compare((*it).first, ckdSmiley)) return TRUE;
    }
    return FALSE;
}

void ConfigDialog::updateTabPosition()
{
    switch(m_preferences.m_tabPosition) {
        case 0: //bottom
            {
                m_tabs->setTabStyle(TABBOOK_BOTTOMTABS);
                for(FXint i = 0; i<m_tabs->numChildren(); i+=2)
                {
                    static_cast<FXTabItem*>(m_tabs->childAtIndex(i))->setTabOrientation(TAB_BOTTOM);
                }
                FXuint packing = m_tabs->getPackingHints();
                packing &= ~PACK_UNIFORM_WIDTH;
                m_tabs->setPackingHints(packing);
            }break;
        case 1: //left
            {
                m_tabs->setTabStyle(TABBOOK_LEFTTABS);
                for(FXint i = 0; i<m_tabs->numChildren(); i+=2)
                {
                    static_cast<FXTabItem*>(m_tabs->childAtIndex(i))->setTabOrientation(TAB_LEFT);
                }
                FXuint packing = m_tabs->getPackingHints();
                packing |= PACK_UNIFORM_WIDTH;
                m_tabs->setPackingHints(packing);
            }break;
        case 2: //top
            {
                m_tabs->setTabStyle(TABBOOK_TOPTABS);
                for(FXint i = 0; i<m_tabs->numChildren(); i+=2)
                {
                    static_cast<FXTabItem*>(m_tabs->childAtIndex(i))->setTabOrientation(TAB_TOP);
                }
                FXuint packing = m_tabs->getPackingHints();
                packing &= ~PACK_UNIFORM_WIDTH;
                m_tabs->setPackingHints(packing);
            }break;
        case 3: //right
            {
                m_tabs->setTabStyle(TABBOOK_RIGHTTABS);
                for(FXint i = 0; i<m_tabs->numChildren(); i+=2)
                {
                    static_cast<FXTabItem*>(m_tabs->childAtIndex(i))->setTabOrientation(TAB_RIGHT);
                }
                FXuint packing = m_tabs->getPackingHints();
                packing |= PACK_UNIFORM_WIDTH;
                m_tabs->setPackingHints(packing);
            }break;
        default:
            {
                m_tabs->setTabStyle(TABBOOK_BOTTOMTABS);
                for(FXint i = 0; i<m_tabs->numChildren(); i+=2)
                {
                    static_cast<FXTabItem*>(m_tabs->childAtIndex(i))->setTabOrientation(TAB_BOTTOM);
                }
                FXuint packing = m_tabs->getPackingHints();
                packing &= ~PACK_UNIFORM_WIDTH;
                m_tabs->setPackingHints(packing);
            }
    }
}

